Index: fact/tools/hvMCUtest/HV.cc
===================================================================
--- fact/tools/hvMCUtest/HV.cc	(revision 12139)
+++ fact/tools/hvMCUtest/HV.cc	(revision 12139)
@@ -0,0 +1,163 @@
+
+/********************************************************************\
+
+  Name:         HV.cc
+
+  Created by:   Sebastian Commichau, November 2008
+                commichau@phys.ethz.ch
+
+  Contents:     Main class for HV supply
+                
+\********************************************************************/
+
+#include "HV.h"
+
+extern bool Verbose;
+
+//
+// Constructor
+//
+HVBoard::HVBoard(int DeviceNumber, char *DeviceName) {
+   
+  char Buffer[MAX_COM_SIZE];
+  struct termios tio;
+ 
+  fTimeOut  = 10;
+  BoardNumber = DeviceNumber;
+  BoardName = DeviceName;
+  LastWrapCount = -1;
+  
+  // Open device
+  snprintf(Buffer, MAX_COM_SIZE, "/dev/%s",DeviceName);
+  if ((fDescriptor = open(Buffer, O_RDWR|O_NOCTTY|O_NDELAY)) == -1) {
+    printf("Error: Could not open device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno));
+    return;
+  }
+
+  // Get current serial port settings
+  if (tcgetattr(fDescriptor, &tio) == -1) {
+    printf("Error: tcgetattr() failed on device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno));
+    return;   
+  }
+
+  // Set baudrate and raw mode
+  if (cfsetspeed(&tio, BAUDRATE) == -1) printf("Error: Could not set baud rate of device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno));
+  cfmakeraw(&tio);
+  if (tcsetattr(fDescriptor, TCSANOW, &tio ) == -1) printf("Error: tcsetattr() failed on device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno));
+
+  return;
+}
+
+//
+// Destructor
+//
+HVBoard::~HVBoard() {
+
+  if(fDescriptor != -1) close(fDescriptor);
+}
+
+
+// Communicate: Write and read from HV Board until fTimeOut has been reached 
+//
+// Returns: 0 error, 1 success, -1 fTimeOut exceeded
+int HVBoard::Communicate(unsigned char* wbuf, int Bytes) {
+
+  unsigned char rbuf[RBUF_LEN];
+  int ret;
+  fd_set SelectDescriptor;
+
+  Status.BoardNumber = -1;
+	
+  // === Write data ===
+  ret = write(fDescriptor, wbuf, Bytes);
+  if (ret == -1) {
+    printf("Error: Could not write data (%d/%s)\n", errno, strerror(errno));
+    return 0;
+  }
+  else if (ret < Bytes) {
+    printf("Error: Could write only %d of %d bytes\n", ret, Bytes);
+    return 0;
+  }
+  if (Verbose) {
+	printf("  %d byte(s) written: ", Bytes);
+	for (int i=0; i<Bytes; i++) printf(" %#.2x", wbuf[i]);
+	printf("\n");
+  }
+	sleep (2);
+  // === Try to read until time-out ===
+  FD_ZERO(&SelectDescriptor);   FD_SET(fDescriptor, &SelectDescriptor);
+  struct timeval WaitTime = {(long) fTimeOut, (long) ((fTimeOut-(long) fTimeOut)*1e6)};
+  if (select(fDescriptor+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
+    printf("Error with select() (%d/%s)\n", errno,strerror(errno));
+    return 0;
+  }
+
+  // Time-out expired?
+  if (!FD_ISSET(fDescriptor, &SelectDescriptor)) {
+    printf("Time-out of %.2f seconds expired while reading\n", fTimeOut);
+    return -1;
+  }
+
+  // Read error?    
+  if ((ret = read(fDescriptor, rbuf, RBUF_LEN)) == -1) {
+    printf("Read error (%d/%s)\n", errno, strerror(errno));
+    return 0;
+  }
+  
+  // Print result in hexadecimal and binary representation 
+  if (Verbose) {
+	printf("  %d byte(s) read: \n", ret);
+	// in case rbuf has no '\0' at its last position, the printf would go berserk!
+	// I put an '\0' at the end of the received bytes
+	rbuf[ret]='\0';
+	printf("%s\n",rbuf);
+  }
+	
+  return 1;
+}
+
+
+// System reset of HV board
+int HVBoard::SystemReset() {
+  
+  unsigned char wbuf[] = {0,0,0};
+  return Communicate(wbuf, 3);
+}
+
+
+// Read channel status
+int HVBoard::ReadChannel(int Chain, int Channel) {
+  
+  unsigned char wbuf[] = {1<<5 | Chain<<1 | (Channel&16)>>4, Channel<<4, 0};
+  return Communicate(wbuf, 3);
+}
+
+
+// Global set
+int HVBoard::GlobalSet(int Voltage) {
+  
+  unsigned char wbuf[] = {1<<6 , Voltage>>8, Voltage};
+  return Communicate(wbuf, 3);
+}
+
+
+// Channel set
+int HVBoard::ChannelSet(int Chain, int Channel, int Voltage) {
+  
+  unsigned char wbuf[] = {3<<5 |  Chain<<1 | (Channel&16)>>4, Channel<<4 | Voltage>>8, Voltage};
+  return Communicate(wbuf, 3);
+}
+
+
+// Synchronize board
+bool HVBoard::SynchBoard() {
+  
+  unsigned char wbuf = 0;
+  int trial = 0, ret;
+  
+  while(++trial<=3) {
+    if((ret = Communicate(&wbuf, 1)) == 1) return true;
+    if (ret==0) break;
+  }
+  return false;
+}
Index: fact/tools/hvMCUtest/HV.h
===================================================================
--- fact/tools/hvMCUtest/HV.h	(revision 12139)
+++ fact/tools/hvMCUtest/HV.h	(revision 12139)
@@ -0,0 +1,52 @@
+#ifndef HV_H_SEEN
+#define HV_H_SEEN
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <termios.h>	    // POSIX terminal control definitions
+#include <fcntl.h>  	    // File control definitions
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#define MAX_COM_SIZE 1000   // Maximum text buffer size
+#define RBUF_LEN 255  	    // Maximum read buffer length
+#define BAUDRATE B9600    // Baudrate for serial communication
+
+#define MAX_NUM_BOARDS 13	// Maximum number of boards per crate
+#define NUM_CHANNELS 32		// Channels per bias board
+
+class HVBoard {
+    
+  public:
+   HVBoard(int, char *);
+   ~HVBoard();
+
+	struct {
+	  int BoardNumber;
+	  bool WrapOK;
+	  int WrapCounter;
+	  bool Acknowledge;
+	  int Current;
+	  bool Overcurrent;
+	  bool Reset;
+	} Status;
+
+   int fDescriptor; 
+   int LastWrapCount;
+   double fTimeOut;      // [s] timeout to return from read 
+  
+   char *BoardName; 
+   int BoardNumber;
+
+   int SystemReset();
+   int ReadChannel(int, int);
+   int GlobalSet(int);
+   int ChannelSet(int, int, int);
+   bool SynchBoard();
+   int Communicate(unsigned char*, int);
+};
+
+#endif
Index: fact/tools/hvMCUtest/Makefile
===================================================================
--- fact/tools/hvMCUtest/Makefile	(revision 12139)
+++ fact/tools/hvMCUtest/Makefile	(revision 12139)
@@ -0,0 +1,19 @@
+#
+#  Makefile vchvtest
+#
+TARGET = hvMCUtest
+SOURCES = $(TARGET).cc HV.cc
+OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
+INCDIRS   = -I.
+
+CPPFLAGS = -O3 -Wall
+LIBS = -L /usr/lib/termcap/ -lstdc++ -lreadline -ltermcap
+
+
+$(TARGET): $(OBJECTS)
+	$(CC) $(CPPFLAGS) -o $@ $(OBJECTS) $(LIBS)
+
+clean:
+	@rm -f $(OBJECTS)
+	@rm -f *~
+	@rm -f $(TARGET)
Index: fact/tools/hvMCUtest/hvMCUtest.cc
===================================================================
--- fact/tools/hvMCUtest/hvMCUtest.cc	(revision 12139)
+++ fact/tools/hvMCUtest/hvMCUtest.cc	(revision 12139)
@@ -0,0 +1,450 @@
+/**************************************************************\
+
+  Test program for new bias supply
+
+  Oliver Grimm
+  
+\**************************************************************/
+
+#include <stdio.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <ctype.h>
+#include <sys/time.h>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "HV.h"
+
+#define MAX_NUM_TOKEN 10
+
+
+// Global variables
+HVBoard **fHVBoard;
+const char *Param[MAX_NUM_TOKEN]; // For parser
+int NParam;
+int NumCrates;
+int FirstCrate;
+int LastCrate;
+bool Repeat = false;
+bool Verbose;
+
+// Function prototypes
+void cmd_crate();   	void cmd_status();
+void cmd_timeout(); 	void cmd_synch();
+void cmd_send();    	void cmd_rst();
+void cmd_rd();	    	void cmd_gs();
+void cmd_cs();	    	void cmd_exit();
+void cmd_help();	void cmd_repeat();
+void cmd_config();	void cmd_rate();
+void cmd_test();
+
+int ParseInput(char*, const char *Param[]);
+bool Match(const char *, const char *);
+bool ConvertToDouble(const char *, double *);
+bool ConvertToInt(const char *, int *);
+
+// Branch table for command evaluation
+static const struct CL_Struct { const char *Name;    
+                	  void (*CommandPointer)();
+			  int MinNumParameter;
+			  const char *Parameters;
+			  const char *Help;
+			  bool Repeatable;
+  } CommandList[] = 
+  {{"crate", &cmd_crate, 0, "<i> [j] | <all>" ,"Address crate i, crates i-j, all crates", false},
+   {"status", &cmd_status, 0, "[i]", "Show status information (for board i)", false},
+   {"config", &cmd_config, 0, "", "Show crate configuration", false},
+   {"timeout", &cmd_timeout, 1, "<secs>", "Set timeout to return from read", false},
+   {"synch", &cmd_synch, 0, "", "Synchronize board(s)", false},
+   {"send", &cmd_send, 1, "<byte1> [byte2] ...", "Send bytes and wait for response", true},
+   {"rst", &cmd_rst, 0, "", "System reset", true},
+   {"rd", &cmd_rd, 2, "<Board> <Channel>", "Read status", true},
+   {"gs", &cmd_gs, 1, "<Voltage>", "Global voltage set", true},
+   {"cs", &cmd_cs, 3, "<Board> <Channel> <Voltage>", "Set channel to voltage", true},
+   {"rate", &cmd_rate, 1, "<n>", "Make n 'rd 0 0' cycles and measure time", false},
+   {"repeat", &cmd_repeat, 1, "<on|off>", "Command repetition (ENTER to stop)", false},
+   {"test", &cmd_test, 1, "<Voltage>", "Set all channels consecutively", false},   
+   {"exit", &cmd_exit, 0, "", "Exit program", false},
+   {"help", &cmd_help, 0, "", "Print help", false}};
+
+
+// ================  Main program  ================
+int main(int argc, char *argv[]) {
+
+  char Prompt[MAX_COM_SIZE], *Command = NULL;
+  struct termios Termios, Termios_orig;
+
+  printf("\n*** vchvtest (built %s, %s; O. Grimm) ***\n\n",__DATE__,__TIME__);
+  if (argc == 1) {
+    printf("Note: Use FTDI serial numbers as arguments to connect\n");
+  }
+	
+
+  // Initialize status variables
+  NumCrates = 0;
+  FirstCrate  = 0;
+  LastCrate   = -1;
+
+  // Open HV devices
+  fHVBoard = new HVBoard* [argc-1];
+  for (int i=1; i<argc; i++) {
+    fHVBoard[NumCrates] = new HVBoard(i-1, argv[i]);
+    if(fHVBoard[NumCrates]->fDescriptor != -1) NumCrates++;
+    else delete fHVBoard[NumCrates];
+  }
+  LastCrate = NumCrates-1;
+
+  // Set terminal to read single chars
+  if (tcgetattr (1, &Termios_orig) == -1) {
+    printf("Error with tcgetattr() (%s)\n", strerror(errno));
+    exit(EXIT_FAILURE);
+  }
+  Termios = Termios_orig;
+  Termios.c_lflag &= ~(ICANON | ECHO);
+
+  // Command loop
+  while (true) {
+    if (Command != NULL) free(Command);  // Free command buffer
+    
+    // Assemble prompt
+    if (NumCrates == 0) snprintf(Prompt, sizeof(Prompt), "HV> ");
+    else if (FirstCrate == LastCrate) snprintf(Prompt, sizeof(Prompt), "HV|B%d> ",FirstCrate);
+    else snprintf(Prompt,sizeof(Prompt),"HV|B%d-%d> ",FirstCrate,LastCrate);
+
+    // Read command from console
+    Command = readline(Prompt);
+    if (Command==NULL) {
+      printf("Error reading command line input\n");
+      continue;
+    }
+    if(strlen(Command)>0) add_history(Command);
+    else continue;
+    
+	// Set terminal to return single chars
+	if (tcsetattr (1, 0, &Termios) == -1) {
+      printf("Error with tcsetattr() (%s)\n", strerror(errno));
+      exit(EXIT_FAILURE);
+    }
+
+	// Defualt is verbose response
+	Verbose = true;
+
+    // Process command
+    for(int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = "";  // All pointers point initially to empty string
+    NParam = ParseInput(Command, Param);
+
+    bool Found=false;
+    int N;
+    for(unsigned int CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++) {
+      if (Match(Param[0], CommandList[CmdNumber].Name)) {
+        if(NParam-1 < CommandList[CmdNumber].MinNumParameter) {
+    	  printf("Usage: %s %s\n", CommandList[CmdNumber].Name, CommandList[CmdNumber].Parameters);
+	    }
+		else do {
+		  (*CommandList[CmdNumber].CommandPointer)();
+		  ioctl(STDIN_FILENO, FIONREAD, &N);
+		} while(CommandList[CmdNumber].Repeatable && Repeat && N==0);
+        Found = true;
+		break;
+      }
+	} // for()
+	
+    if (!Found) printf("Unknown command '%s'\n",Param[0]);
+	
+	// Set terminal back to line buffering
+	if (tcsetattr (1, 0, &Termios_orig) == -1) {
+      printf("Error with tcsetattr() (%s)\n", strerror(errno));
+      exit(EXIT_FAILURE);
+    }
+  } // while()
+}
+
+// Print help
+void cmd_help() {
+
+  char Buffer[MAX_COM_SIZE];
+  for(unsigned int i=0; i<sizeof(CommandList)/sizeof(CL_Struct); i++) {
+    snprintf(Buffer, sizeof(Buffer), "%s %s", CommandList[i].Name, CommandList[i].Parameters);
+    printf("%-32s%s\n", Buffer, CommandList[i].Help);
+  }     
+  printf("\nAccepted prefixes for integers: 'b' binary, '0' octal, '0x' hexadecimal\n");
+} 
+
+// Select board(s)
+void cmd_crate() {
+
+  int Number;
+
+  if (Match(Param[1],"all")) {
+    FirstCrate = 0;
+    LastCrate = NumCrates-1;
+    return;
+  } 
+  if (NParam>=2 && ConvertToInt(Param[1], &Number) && Number>=0 && Number<NumCrates) {
+    FirstCrate = Number;
+    LastCrate = FirstCrate;
+  }
+  if (NParam==3 && ConvertToInt(Param[2], &Number) && Number>=FirstCrate && Number<NumCrates) {
+    LastCrate = Number;
+  }
+} 
+
+// System reset
+void cmd_rst() {
+
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    if (fHVBoard[i]->SystemReset() == 1) {
+      printf("Reset of board %d\n", fHVBoard[i]->BoardNumber);
+    }
+    else printf("Error: Could not reset board %d\n",fHVBoard[i]->BoardNumber);    
+  } 
+}
+
+// Read channel
+void cmd_rd() {
+
+  int Board=0, Channel=0;
+
+  if (!ConvertToInt(Param[1], &Board) || !ConvertToInt(Param[2], &Channel)) return;
+
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    if (fHVBoard[i]->ReadChannel(Board, Channel) != 1) {
+      printf("Error: Could not read from board %d\n", fHVBoard[i]->BoardNumber);
+    }    
+  } 
+}
+
+// Read channel
+void cmd_gs() {
+
+  int Voltage;
+
+  if (!ConvertToInt(Param[1], &Voltage)) return;
+
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    if (fHVBoard[i]->GlobalSet(Voltage) != 1) {
+      printf("Error: Could not global set board %d\n", fHVBoard[i]->BoardNumber);
+    }    
+  } 
+}
+
+// Read channel
+void cmd_cs() {
+
+  int Board=0, Channel=0, Voltage=0;
+
+  if (!ConvertToInt(Param[1], &Board) || !ConvertToInt(Param[2], &Channel) || !ConvertToInt(Param[3], &Voltage)) return;
+
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    if (fHVBoard[i]->ChannelSet(Board, Channel, Voltage) != 1) {
+      printf("Error: Could not channel set board %d\n", fHVBoard[i]->BoardNumber);
+    }    
+  } 
+}
+
+// Synchronize boards
+void cmd_synch() {
+
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    if (fHVBoard[i]->SynchBoard()) printf("Synchronized board %d\n", fHVBoard[i]->BoardNumber);
+    else printf("Failed to synchronize board %d\n", fHVBoard[i]->BoardNumber);
+  } 
+}
+
+// Switch on all channels consecutively for cabling test 
+void cmd_test() {
+
+  Verbose = false;
+
+  // Loop over crates
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    printf("Testing board %d  (q to stop, any other key to continue)\n", fHVBoard[i]->BoardNumber);
+    if (fHVBoard[i]->GlobalSet(0) != 1) {
+      printf("Error: Could not global set board to zero\n");
+	  return;
+    }    
+
+	for (int k=0; k<MAX_NUM_BOARDS; k++) for (int j=0; j<NUM_CHANNELS; j++) {
+	  printf("Board %d, channel %d\n", k, j);
+
+	  if (fHVBoard[i]->ChannelSet(k, j, atoi(Param[1])) != 1) {
+        printf("  Error setting voltage\n");
+		return;
+	  }
+	  
+	  if (getchar() == 'q') return; 
+	}
+  } 
+}
+
+// Send bytes and wait for response
+void cmd_send() {
+
+  unsigned char wbuf[MAX_NUM_TOKEN];
+  int Number;
+
+  for (int j=1; j<NParam; j++) {
+    ConvertToInt(Param[j], &Number);
+    wbuf[j-1] = (unsigned char) Number; 
+  }
+
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+    fHVBoard[i]->Communicate(wbuf, NParam-1);
+  } 
+}
+
+// Measure read speed
+void cmd_rate() {
+
+  struct timeval Start, End;
+  int N = atoi(Param[1]);
+
+  if (N < 1) return;
+  Verbose = false;
+
+  gettimeofday(&Start, NULL);
+  for (int i=0; i<=N; i++) fHVBoard[0]->ReadChannel(0, 0);
+  gettimeofday(&End, NULL);
+
+  double Diff = ((End.tv_sec-Start.tv_sec)*1e6 + End.tv_usec-Start.tv_usec) * 1e-6;
+  printf("%d accesses in %f seconds: rate %.0f Hz, period %.2f ms\n", N, Diff, N/Diff, (Diff*1e3)/N); 
+}
+
+// Switch repeat on/off
+void cmd_repeat() {
+
+  if (Match(Param[1],"on")) Repeat = true;
+  else Repeat = false;
+  printf("Auto command repeat is %s\n", Repeat ? "on (Hit return while repeating to stop)" : "off");
+} 
+
+// Print status
+void cmd_status() {
+
+  int Board;
+
+  Verbose = false;
+
+  if (NParam==2 && ConvertToInt(Param[1], &Board)) {
+	for (int i=FirstCrate; i<=LastCrate; i++) {
+	  for (int j=0; j<NUM_CHANNELS; j++) {
+		if (j%4 == 0) printf("\nChannel %2d  ", j);
+    	fHVBoard[i]->ReadChannel(Board, j);
+		if (fHVBoard[i]->Status.BoardNumber == -1) printf("Read error  ");
+		else printf(" %s %s %5d    ", fHVBoard[i]->Status.Overcurrent ? "OC":"--", fHVBoard[i]->Status.Acknowledge ? "OK":"KO",fHVBoard[i]->Status.Current); 
+      }    
+	printf("\n");  
+	}
+  } else {
+	printf(" Auto command repeat is %s\n", Repeat ? "on" : "off");
+	printf(" Total number of HV crates: %d\n", NumCrates);
+	printf(" Active HV crates: %d\n\n", LastCrate - FirstCrate + 1);
+
+	for (int i=FirstCrate; i<=LastCrate; i++) {
+      printf(" Crate %d (%s)   Wrap counter: %d  Time-out: %.2f s\n",
+    	fHVBoard[i]->BoardNumber, fHVBoard[i]->BoardName,
+    	fHVBoard[i]->LastWrapCount, fHVBoard[i]->fTimeOut);
+	}
+  }
+} 
+
+// Print crate configuration
+void cmd_config() {
+
+  Verbose = false;
+  
+  for (int i=FirstCrate; i<=LastCrate; i++) {
+	for (int j=0; j<MAX_NUM_BOARDS; j++) {
+	  printf("Board %2d  ", j);
+      fHVBoard[i]->ReadChannel(j, 0);
+	  if (fHVBoard[i]->Status.BoardNumber == -1) printf("Read error\n");
+	  else printf(" %s\n", fHVBoard[i]->Status.Acknowledge ? "OK":"KO"); 
+    }    
+  }
+} 
+
+// Set timeout to return from read
+void cmd_timeout() {
+
+  double Timeout;
+
+  if (!ConvertToDouble(Param[1], &Timeout)) return;   
+  for (int i=0; i<NumCrates; i++) fHVBoard[i]->fTimeOut = Timeout;
+}
+
+// Exit program (delete HV boards)
+void cmd_exit() {
+
+  for (int i=0; i<NumCrates; i++) delete fHVBoard[i];
+  delete[] fHVBoard;
+
+  exit(EXIT_SUCCESS);
+}
+       
+
+// Parse command line for white space and double-quote separated tokens 
+int ParseInput(char* Command, const char *Param[]) {
+
+  int Count=0;
+   
+  while(Count<MAX_NUM_TOKEN) {
+    while (isspace(*Command)) Command++; // Ignore initial white spaces
+    if(*Command=='\0') break;
+    if (*Command == '\"') {
+      Param[Count] = ++Command;
+      while(*Command!='\"' && *Command!='\0') Command++;
+    }
+    else {
+      Param[Count] = Command;
+      while(!isspace(*Command) && *Command!='\0') Command++;
+    }
+    if(*Command != '\0') *Command++ = '\0';
+    Count++;
+  }
+  return Count;
+}
+
+
+// Check if two strings match (min 1 character must match)
+bool Match(const char *str, const char *cmd) {
+
+  return strncasecmp(str,cmd,strlen(str)==0 ? 1:strlen(str)) ? false:true;
+}
+
+// Convert string to double
+// Returns false if conversion did not stop on whitespace or EOL character
+bool ConvertToDouble(const char *String, double *Result) {
+
+  char *EndPointer;
+  
+  *Result = strtod(String, &EndPointer);
+  if(!isspace(*EndPointer) && *EndPointer!='\0') {
+    printf("Error: Wrong number format\n");
+    return false;
+  }
+  return true;
+}
+
+// Convert string to int
+// Returns false if conversion did not stop on whitespace or EOL character
+// Accepted prefixes: 'b' binary, '0' octal, '0x' hexadecimal
+bool ConvertToInt(const char *String, int *Result) {
+
+  char *EndPointer;
+  int Base = 0;
+  
+  if (tolower(*String) == 'b') {
+    String++;
+    Base = 2;
+  }
+    
+  *Result = (int) strtol(String, &EndPointer, Base);
+  if(!isspace(*EndPointer) && *EndPointer!='\0') {
+    printf("Error: Wrong number format\n");
+    return false;
+  }
+  return true;
+}
