Skip to content. | Skip to navigation

Personal tools

parse.cpp

parse.cpp

parse.cpp

/////////////////////////////////////////////////////////////////////////////
// PARSE.CPP
//
//  Last updated: 4/20/2006
//
//  Part of the source code for the M3 Program
//
// This file contains the functions that parse serial and keyboard input,
// and execute the appropriate functions to carry out the commands.
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// ParseKB: Parse a keyboard command line
int ParseKB(char *line,int SerialCommand,char *errmsg)
// This routine parses a keyboard command-line, and executes the
// appropriate code to accomplish the command.
// Returns a 0 if OK, >= 1 on a parse error
// SerialCommand = 1 if this is a free-form serial line we're parsing,
// SerialCommand = 0 if this is a local keyboard command.
// errmsg is filled with an error message to send to upstream computers.
{
  int CmdError = 0;

  // Temporary parsing variables
  float ftemp,ftemp2,ftemp3;
  int ftemp1;
  double longftemp;
  int itemp;
  dword longitemp;
  char Cmds[10][30]; // Tokenized command line
  int CmdCount = 0;  // Number of command tokens

  if (!SerialCommand)
    {
      // Display the entered command
      InputLog->Add("* %s",0,line);
      InputLog->DisplayAll();
    }

  Log->Add("ParseKB(%d): Parsing \"%s\"",VERBOSE,__LINE__,line);

  // Blank input line
  if (strlen(line) == 0)
    return(0);

  // Break the line up into command tokens
  strncpy(Cmds[0],strtok(line," "),29);

  do {
    CmdCount++;
    strncpy(Cmds[CmdCount],strtok(NULL," "),29);
  } while ( (strcmp(Cmds[CmdCount],NULL)) && (CmdCount < 9) );

  // Identify the command and execute

  // Quit
  if ( ((!strcmp(Cmds[0],"Q")) || (!strcmp(Cmds[0],"EXIT")))
       && (CmdCount == 1) && !SerialCommand )
    Quit = 1;
  // Toggle stepper power (Tilts, ADC Turret and M3 Turret)
  else if (!strcmp(Cmds[0],"SP") && (CmdCount == 1))
    {
      if (StepperPowerFlag)
	StepperPowerOff(0);
      else
	StepperPowerOn();
    }
  // Toggle ADC stepper power (just the ADC rotators)
  else if (!strcmp(Cmds[0],"ASP") && (CmdCount == 1))
    {
      if (ADCStepperPowerFlag)
	ADCStepperPowerOff(0);
      else
	ADCStepperPowerOn();
    }
  // Toggle tilt brakes
  else if (!strcmp(Cmds[0],"TBRKOFF") && (CmdCount == 1))
    SetParBit(6);
  else if (!strcmp(Cmds[0],"TBRKON") && (CmdCount == 1))
    ClrParBit(6);
  // Terminal on COM1: (Host)
  else if (!strcmp(Cmds[0],"T1") && (CmdCount == 1) && !SerialCommand)
    COMTerminal(0);
  // Terminal on COM2: (DGHs)
  else if (!strcmp(Cmds[0],"T2") && (CmdCount == 1) && !SerialCommand)
    COMTerminal(1);
  // Terminal on COM2: at 300 baud (DGH Setup)
  else if (!strcmp(Cmds[0],"T3") && (CmdCount == 1) && !SerialCommand)
    {
      SetComPortSpeed(1,300);
      COMTerminal(1);
      RestoreComPortSpeed(1);
    }
  // Mirror motions
  else if (!strcmp(Cmds[0],"M") && (CmdCount == 2))
    {
      if (!strcmp(Cmds[1],"UP"))
	Mirror.Up(0);  // This is a "safe" up
      else if (!strcmp(Cmds[1],"DOWN"))
	Mirror.Down();
      else if (!strcmp(Cmds[1],"STOP"))
	Mirror.Stop();
      else
	CmdError = 1;
    }
  // Force mirror up (even in unsafe positions!!!)
  else if (!strcmp(Cmds[0],"FM") && (CmdCount == 2) && !SerialCommand)
    {
      if (!strcmp(Cmds[1],"UP"))
	Mirror.Up(1);
      else
	CmdError = 1;
    }

  // Mirror Turret commands
  else if (!strcmp(Cmds[0],"MT") && (CmdCount == 2))
    {
      if (!strcmp(Cmds[1],"HOME"))                            // Mirror turret home
	M3Turret->Home();
      else if (!strcmp(Cmds[1],"AUX1"))       // Mirror turret to Aux 1
	M3Turret->MovePosition(MTPReverseAux);
      else if (!strcmp(Cmds[1],"AUX2"))               // Mirror turret to Aux 2
	M3Turret->MovePosition(MTPMiddleAux);
      else if (!strcmp(Cmds[1],"AUX3"))               // Mirror turret to Aux 3
	M3Turret->MovePosition(MTPForwardAux);
      else if (!strcmp(Cmds[1],"NASW"))               // Mirror turret to Nas W
	M3Turret->MovePosition(MTPForward);
      else if (!strcmp(Cmds[1],"NASE"))               // Mirror turret to Nas E
	M3Turret->MovePosition(MTPReverse);
      else if (!strcmp(Cmds[1],"LOCK"))               // Lock mirror turret pin
	M3TurretPin.Lock(0);
      else if (!strcmp(Cmds[1],"UNLOCK"))     // Unlock mirror turret pin
	M3TurretPin.Unlock(0);
      else if (!strcmp(Cmds[1],"STOP"))               // Stop M3 Turret and pin motion
	{
	  M3Turret->AbortMove();
	  //Should M3 Turret Pin be stopped?
	}
      // Move Mirror turret given number of steps
      else if (sscanf(Cmds[1],"%ld",&longitemp) == 1)
	M3Turret->MoveSteps(longitemp,0);
      else
	CmdError = 1;
    } // End of mirror turret commands

  // ADC Turret commands
  else if (!strcmp(Cmds[0],"AT") && (CmdCount == 2))
    {
      if (!strcmp(Cmds[1],"HOME"))  // ADC Turret home
	ADCTurret->Home();
      else if (!strcmp(Cmds[1],"ADC"))  // ADC Turret move to ADC position
	ADCTurret->MovePosition(ATPIndex);
      else if (!strcmp(Cmds[1],"NOADC"))  // ADC Turret move to non-ADC position
	{
	  ADCTurret->MovePosition(ATPReverse);
	  // Put ADC Stepper Power off when not using the ADC lenses
	  ADCStepperPowerOffNow();
	}
      // ADC turret locking is only useful in ADC pos,
      // since NOADC pos don't have support for the lockpin
      else if (!strcmp(Cmds[1],"LOCK"))  // ADC Turret pin lock
	ADCTurretPin.Lock(0);
      else if (!strcmp(Cmds[1],"UNLOCK"))  // ADC Turret pin unlock
	ADCTurretPin.Unlock(0);
      // Move ADC turret given number of steps
      else if (sscanf(Cmds[1],"%ld",&longitemp) == 1)
	ADCTurret->MoveSteps(longitemp);
      else
	CmdError = 1;
    } // End of ADC Turret commands
  // ADC A and B power on
  // ADC Rotator A Commands
  else if (!strcmp(Cmds[0],"ADCA") && (CmdCount == 2))
    {
      // ADC Home
      if (!strcmp(Cmds[1],"HOME"))
	ADCA.Home();
      // ADC Stop
      else if (!strcmp(Cmds[1],"STOP"))
	ADCA.AbortMove();
      // ADC Move Steps
      else if (sscanf(Cmds[1],"S%ld",&longitemp) == 1)
	ADCA.MoveSteps(longitemp,0);
      // ADC Move to Angle (in degrees)
      else if (sscanf(Cmds[1],"%lf",&longftemp) == 1)
	ADCA.MovePosition(longftemp);
      else
	CmdError = 1;
    }
  // ADC Rotator B Commands
  else if (!strcmp(Cmds[0],"ADCB") && (CmdCount == 2))
    {
      // ADC Home
      if (!strcmp(Cmds[1],"HOME"))
	ADCB.Home();
      // ADC Stop
      else if (!strcmp(Cmds[1],"STOP"))
	ADCB.AbortMove();
      // ADC Move Steps
      else if (sscanf(Cmds[1],"S%ld",&longitemp) == 1)
	ADCB.MoveSteps(longitemp,0);
      // ADC Move to Angle (in degrees)
      else if (sscanf(Cmds[1],"%lf",&longftemp) == 1)
	ADCB.MovePosition(longftemp);
      else
	CmdError = 1;
    }
  // ADC Combined Motion Command and ADC Change of Operation Mode Command
  else if (!strcmp(Cmds[0],"ADC") && (CmdCount == 2))
    {
      // Change operation mode to Manual
      if (!strcmp(Cmds[1],"MAN"))
	ADCRotatorsMode = ADCSManual;
      // Change operation mode to Automatic
      else if (!strcmp(Cmds[1],"AUTO"))
	{
	  if (ADCA.Homed && ADCB.Homed)
	    ADCRotatorsMode = ADCSAuto;
	  else
	    InputLog->Add("Home ADCs first",BRIEF);
	}
	else if (!strcmp(Cmds[1],"HOME")) {
		ADCA.Home();
		ADCB.Home();
	}
      // Both ADCs Move to Angle (in degrees), if in manual motion mode
      else if ( (sscanf(Cmds[1],"%lf",&longftemp) == 1) && (ADCRotatorsMode == ADCSManual) )
	MovePositionCombined(longftemp);
      // Don't move when AUTO mode is active
      else if ( (sscanf(Cmds[1],"%lf",&longftemp) == 1) && (ADCRotatorsMode == ADCSAuto) )
	InputLog->Add("ADCs motion in AUTO",BRIEF);
      else
	CmdError = 1;
    }
  // Tilt A Commands
  // HERE ALL THE MOVE COMMANDS STARTS!!!!!!!!!!!!!!!!!!
  else if (!strcmp(Cmds[0],"TA") && (CmdCount == 2))
    {
      // Move tilt A
      if (sscanf(Cmds[1],"%ld",&longitemp) == 1){
       
        StepsArcVolt.ClearVariables();
        StepsArcVolt.TransformSteps[0]=longitemp;
        StepsArcVolt.Steps2VoltTTPS();
        Log->Add("TA: TTPS %4.4f %4.4f %4.4f",StepsArcVolt.TransformTTPS[0]
                                    ,StepsArcVolt.TransformTTPS[1]
                                    ,StepsArcVolt.TransformTTPS[2]);

        Log->Add("TA: LVDTS %4.4f %4.4f %4.4f",StepsArcVolt.TransformLvdts[0]
                                     ,StepsArcVolt.TransformLvdts[1]
                                     ,StepsArcVolt.TransformLvdts[2]);  
	Tilt.MoveSteps(longitemp,0,0);
      }
      else
	CmdError = 1;
    }
  // Tilt B Commands
  else if (!strcmp(Cmds[0],"TB") && (CmdCount == 2))
    {
      // Move tilt B
      if (sscanf(Cmds[1],"%ld",&longitemp) == 1){

        StepsArcVolt.ClearVariables();
        StepsArcVolt.TransformSteps[1]=longitemp;
        StepsArcVolt.Steps2VoltTTPS();
        Log->Add("TB: TTPS %4.4f %4.4f %4.4f",StepsArcVolt.TransformTTPS[0]
                                    ,StepsArcVolt.TransformTTPS[1]
                                    ,StepsArcVolt.TransformTTPS[2]);

        Log->Add("TB: LVDTS %4.4f %4.4f %4.4f",StepsArcVolt.TransformLvdts[0]
                                     ,StepsArcVolt.TransformLvdts[1]
                                     ,StepsArcVolt.TransformLvdts[2]);
	Tilt.MoveSteps(longitemp,1,0);
      }
      else
	CmdError = 1;
    }
  // Tilt C Commands
  else if (!strcmp(Cmds[0],"TC") && (CmdCount == 2))
    {
      // Move tilt C
      if (sscanf(Cmds[1],"%ld",&longitemp) == 1){
        StepsArcVolt.ClearVariables();
        StepsArcVolt.TransformSteps[2]=longitemp;
        StepsArcVolt.Steps2VoltTTPS();
        Log->Add("TC: TTPS %4.4f %4.4f %4.4f",StepsArcVolt.TransformTTPS[0]
                                    ,StepsArcVolt.TransformTTPS[1]
                                    ,StepsArcVolt.TransformTTPS[2]);

        Log->Add("TC: LVDTS %4.4f %4.4f %4.4f",StepsArcVolt.TransformLvdts[0]
                                     ,StepsArcVolt.TransformLvdts[1]
                                     ,StepsArcVolt.TransformLvdts[2]);
	Tilt.MoveSteps(longitemp,2,0);
      }
      else
	CmdError = 1;
    }
  // Compound Tilt Commands
  // PISTON type
  else if (!strcmp(Cmds[0],"PISTON") && (CmdCount == 2))
    {
      // Move tilt A-B-C = millimeters
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
	{
	  longitemp = round(Tilt.Kstepmm * ftemp);
	  if (fabs(ftemp) > 1.0)
	    Log->AddX("Piston move aborted, max 1 mm allowed",20,SHECRED,BRIEF);
	  else
	    {
	      Tilt.MoveSteps(longitemp,0,0);  // Move actuator A
	      Tilt.MoveSteps(longitemp,1,0);  // Move actuator B
	      Tilt.MoveSteps(longitemp,2,0);  // Move actuator C
	    }
	}
      else
	CmdError = 1;
    }
  // Tilt around a horizontal line crossing the middle of M3
  else if (!strcmp(Cmds[0],"TH") && (CmdCount == 2))
    {
      //Tilt A=arcsec & B-C=-arcsec
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
	{
	  longitemp = round(Tilt.Kstepmm * ftemp * Tilt.KKA / (3437.75*60));
          Log->Add("TH: Actuator A steps calculated: %d",longitemp);
	  Tilt.MoveSteps(longitemp,0,0);  // Move actuator A

	  longitemp = -round(Tilt.Kstepmm * ftemp * Tilt.KKB / (3437.75*60));
          Log->Add("TH: Actuator B and C steps calculated: %d",longitemp);
	  Tilt.MoveSteps(longitemp,1,0);  // Move actuator B
	  Tilt.MoveSteps(longitemp,2,0);  // Move actuator C
	}
      else
	CmdError = 1;
    }
  // Tilt around a vertical line crossing the middle of M3
  else if (!strcmp(Cmds[0],"TV") && (CmdCount == 2))
    {
      //Tilt B=arcsec & C=-arcsec
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
	{
	  longitemp = round(Tilt.Kstepmm * ftemp * Tilt.KKC / (3437.75*60));
          Log->Add("TV: Actuator B and C steps calculated: %d",longitemp);
	  Tilt.MoveSteps(longitemp,1,0);  // Move actuator B
	  Tilt.MoveSteps(-longitemp,2,0);  // Move actuator C
	}
      else
	CmdError = 1;
    }
   // HERE ALL THE MOVE COMMANDS ENDS!!!!!!!!!!!!!!!!!!  
// Servo Tilt A
  else if (!strcmp(Cmds[0],"TAS") && (CmdCount == 2))
    {
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
        Tilt.Servo(0,ftemp);
      else
	CmdError = 1;
    }
  // Servo Tilt B
  else if (!strcmp(Cmds[0],"TBS") && (CmdCount == 2))
    {
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
        Tilt.Servo(1,ftemp);
      else
	CmdError = 1;
    }
  // Tilt C servo
  else if (!strcmp(Cmds[0],"TCS") && (CmdCount == 2))
    {
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
        Tilt.Servo(2,ftemp);
      else
	CmdError = 1;
    }
  // Tilt A=B=C servo
  else if (!strcmp(Cmds[0],"TILTS") && (CmdCount == 4))
    {
      if ((sscanf(Cmds[1],"%f",&ftemp) == 1) &&
	  (sscanf(Cmds[2],"%f",&ftemp2) == 1) &&
	  (sscanf(Cmds[3],"%f",&ftemp3) == 1))
	Tilt.ServoAll(ftemp,ftemp2,ftemp3);
      else
	CmdError = 1;
    }
  else if (!strcmp(Cmds[0],"TENASW") && (CmdCount == 2))
    {
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
	{
	  ftemp1 = ftemp;
	  if ((ftemp1 == 20) || (ftemp1 == 25) || (ftemp1 == 30) || (ftemp1 == 35)
	      || (ftemp1 == 40) || (ftemp1 == 45) || (ftemp1 == 50) || (ftemp1 == 55)
	      || (ftemp1 == 60) || (ftemp1 == 65) || (ftemp1 == 70) || (ftemp1 == 75)
	      || (ftemp1 == 80) || (ftemp1 == 85) || (ftemp1 == 90))
	    Tilt.ServoAll(Tilt.TNaswA[ftemp1],Tilt.TNaswB[ftemp1],Tilt.TNaswC[ftemp1]);
	}
      else
	CmdError =1;
    }
  // Pressure/vacuum control commands
  // Toggle pressure
  else if (!strcmp(Cmds[0],"PRESOFF") && (CmdCount == 1))
    SetDigBit(3);
  else if (!strcmp(Cmds[0],"PRESON") && (CmdCount == 1))
    ClrDigBit(3);
  // Toggle vacuum
  else if (!strcmp(Cmds[0],"VACOFF") && (CmdCount == 1))
    SetDigBit(2);
  else if (!strcmp(Cmds[0],"VACON") && (CmdCount == 1))
    ClrDigBit(2);
  // Toggle pressure/vacuum control mode
  else if (!strcmp(Cmds[0],"PVM") && (CmdCount == 1))
    {
      if (PresVacMode == PVMAuto)
	{
	  PresVacMode = PVMOff;
	  SetDigBit(2); // Turn off vacuum
	  SetDigBit(3); // Turn off pressure
	}
      else
	PresVacMode = PVMAuto;
      PresVac.Display();
    }
  // Change Pres/Vac chart scale
  else if (!strcmp(Cmds[0],"PVS") && (CmdCount == 2))
    {
      if (sscanf(Cmds[1],"%f",&ftemp) == 1)
	{
	  ftemp = fabs(ftemp);
	  if (ftemp > 5.0)
	    ftemp = 5.0;
	  PresVacChart.SetScale(ftemp);
	  PresVac.Display();
	}
      else
	CmdError = 1;
    }

  // Mirror latches manual control. USE WITH EXTREME CAUTION!!!
  else if (!strcmp(Cmds[0],"LAT") && (CmdCount == 2))
    {
      if (!strcmp(Cmds[1],"OPN"))
	Mirror.OpenLatches();
      else if (!strcmp(Cmds[1],"CLS"))
	Mirror.CloseLatches();
      else
	CmdError = 1;
    }

  else if (!strcmp(Cmds[0],"NASW") && (CmdCount == 1))
    {
      // Mirror turret to Nas W
      M3Turret->MovePosition(MTPForward);
      //Tilt.ServoAll(Tilt.TNASW[0],Tilt.TNASW[1],Tilt.TNASW[2]);
      M3Turret->GroupFlag = 6;
    }
  else if (!strcmp(Cmds[0],"AUX3") && (CmdCount == 1))
    {
      // Mirror turret to Aux 3
      M3Turret->MovePosition(MTPForwardAux);
      //Tilt.ServoAll(Tilt.TAUX3[0],Tilt.TAUX3[1],Tilt.TAUX3[2]);
      M3Turret->GroupFlag = 5;
    }
  else if (!strcmp(Cmds[0],"AUX2") && (CmdCount == 1))
    {
      // Mirror turret to Aux 2
      M3Turret->MovePosition(MTPMiddleAux);
      //Tilt.ServoAll(Tilt.TAUX2[0],Tilt.TAUX2[1],Tilt.TAUX2[2]);
      M3Turret->GroupFlag = 4;
    }
  else if (!strcmp(Cmds[0],"AUX1") && (CmdCount == 1))
    {
      // Mirror turret to Aux 1
      M3Turret->MovePosition(MTPReverseAux);
      //Tilt.ServoAll(Tilt.TAUX1[0],Tilt.TAUX1[1],Tilt.TAUX1[2]);
      M3Turret->GroupFlag = 3;
    }
  else if (!strcmp(Cmds[0],"NASE") && (CmdCount == 1))
    {
      // Mirror turret to Nas E
      M3Turret->MovePosition(MTPReverse);
      //Tilt.ServoAll(Tilt.TNASE[0],Tilt.TNASE[1],Tilt.TNASE[2]);
      M3Turret->GroupFlag = 2;
    }

  // Verbose command
  else if (!strcmp(Cmds[0],"VERB") && (CmdCount == 2))
    {
      if (sscanf(Cmds[1],"%d",&itemp) != 1)
	CmdError = 1;
      else if ((itemp < 0) || (itemp > 2))
	CmdError = 1;
      else
	{
	  Log->VerboseLevel = itemp;
	  InputLog->Add("Verbose level = %d",0,itemp);
	}
    }
  else
    CmdError = 1;

  if (CmdError == 1)
    strcpy(errmsg,"Command decode error");
  // Display error message locally if necessary
  if ((CmdError >= 1) && (!SerialCommand))
    InputLog->Add("  %s",BRIEF,errmsg);
  return(CmdError);
}

/////////////////////////////////////////////////////////////////////////////
// ParseSer: Parse a serial command line
void ParseSer(char line[80])
// This routine parses a command line from the serial port, and executes the
// appropriate code to accomplish the command.
{
  int i,e;
  char s[255];
  char temp[80];
  struct dostime_t t;

  Log->Add("ParseSer(%d): Parsing \"%s\"",VERBOSE,__LINE__,line);
  // Is message for us?
  if ((line[0] == Prompt) && (line[1] == Address))
    {
      switch (line[2])
	{
	  // Send next EDS message
	case '2':
	  EDSLog.SendNextMessage();break;
	  // Repeat last EDS message
	case '3':
	  EDSLog.RepeatLastMessage();break;
	  // Set UT
	case '4':
	  {
	    if (VerifyChecksum(line) ||
		(sscanf(&line[3],"%2d%2d%2d%2d",&t.hour,&t.minute,&t.second,
			&t.hsecond) != 4))
	      {
		RespondToHost("40\r");
		Log->AddX("Incorrectly formatted UT message from TCS",1,LIGHTRED,0);
	      }
	    else
	      {
		Log->AddX("UT set by TCS to %02d %02d %02d.%02d",998,LIGHTGREEN,0,
			  t.hour,t.minute,t.second,t.hsecond);
		settime(&t);
		RespondToHost("41\r");
	      }
	  } break;
	  // Elevation from TCS
	case '5':
	  {
	    if (sscanf(&line[3],"%lf",&telel) != 1)
	      RespondToHost("50\r");
	    else
	      {
		RespondToHost("51\r");
		ADCRotatorsAngle();
	      }  
	  } break;
	  // Free-form command
	case '9':
	  {
	    if (VerifyChecksum(line) ||
		(line[3] < '0') || (line[3] > '9') ||
		(line[4] < '0') || (line[4] > '9'))
	      RespondToHost("?\r");
	    else
	      {
		i = (line[3] - '0') * 10 + line[4] - '0';
		if (strlen(line) != i + 7)
		  RespondToHost("?\r");
		else
		  {
		    strncpy(s,&line[5],i);
		    s[i] = 0;
		    if (e = ParseKB(s,1,temp))
		      {
			sprintf(s,"9%d%02d%s",e,strlen(temp),temp);
			RespondToHostWithChecksum(s);
		      }
		    else
		      RespondToHostWithChecksum("9000");
		  }
	      }
	  } break;
	default:
	  RespondToHost("?\r");
	}
    }
}

/////////////////////////////////////////////////////////////////////////////
// Parse: Checks for keyboard and serial input
void Parse()
{
  int c;
  char temp[255];

  // Check for scroll-lock, and pause log if necessary
  Log->Paused = (*((byte *)0x417)) & 0x10;

  // Check for a character from the keyboard
  while (kbhit())
    {
      c = toupper(getch());
      if (HelpFlag)
	{
	  HelpFlag = 0;
	  DisplayEnable = 1;
	  // Restore normal display
	  InitDisplay();
	  return;
	}
      // On a carriage return, we either need to parse a keyboard command
      // line (local mode), or check for the serial to keyboard mode change
      // password.
      if (c == 0)
	{
	  // Check for arrow and pgup/pgdn keys for log scrolling
	  c = getch();
	  switch(c)
	    {
	    case 72:
	      // Up arrow
	      {
		Log->Up();
	      } break;
	    case 80:
	      // Down arrow
	      {
		Log->Down();
	      } break;
	    case 73:
	      // Page up
	      {
		Log->PageUp();
	      } break;
	    case 81:
	      // Page down
	      {
		Log->PageDown();
	      } break;
	    case 71:
	      // Home
	      {
		Log->Home();
	      } break;
	    case 79:
	      // End
	      {
		Log->End();
	      } break;
	    case 75:
	      // Left
	      {
		Log->Left();
	      } break;
	    case 77:
	      // Right
	      {
		Log->Right();
	      } break;
	    case 59:
	      // User hit F1, so display help
	      {
		DisplayHelp();
		DisplayEnable = 0;
		HelpFlag = 1;
	      } break;
	    case 60:
	      // User hit F2, so dump log
	      {
		Log->Dump(0);
	      } break;
	    case 61:
	      // F3 = Dump Screen
	      {
		ScreenDump();
		Log->AddX("Screen dumped to SCREEN.BMP",990,SHECGREEN,0);
	      } break;
	    }
	}
      // User hit enter
      else if (c == 13)
	{
	  CmdLine("");
	  ParseKB(kbline,0,temp);
	  CmdLine("");
	  // After processing a keyboard line, clear the buffer
	  kbline[0] = 0;
	  CmdLine(kbline);
	}
      // Process a backspace
      else if (c == '\b')
	{
	  if (strlen(kbline) > 0)
	    {
	      kbline[strlen(kbline) - 1] = 0;
	      CmdLine(kbline);
	    }
	}
      // User hit Escape: stop mirror/turret pins
      else if (c == 27)
	{
	  Mirror.Stop();
	  M3Turret->AbortMove();
	  ADCTurret->AbortMove();
	  ADCA.AbortMove();
	  ADCB.AbortMove();
	  Tilt.AbortMove();
	  //M3TurretPin.Stop();
	  ADCTurretPin.Stop();
	}
      else if (strlen(kbline) < 70)
	{
	  // Otherwise, add the new character to the current buffer
	  kbline[strlen(kbline)+1] = 0;
	  kbline[strlen(kbline)] = c;
	  CmdLine(kbline);
	}
    }

  // Check for a command from the serial port
  if (SerialCharReady(Host))
    {
      c = toupper(SerialGetChar(Host));
      // On a carriage return, parse the serial command line
      if (c == 13)
	{
	  ParseSer(serline);
	  serline[0] = 0;
	  ClearSerialBuffer(0);
	}
      // On receiving our prompt character, flush the serial receive line
      else if (c == Prompt)
	{
	  serline[0] = Prompt;
	  serline[1] = 0;
	}
      // Otherwise, add the character to the buffer
      else if (strlen(serline) < 79)
	{
	  serline[strlen(serline)+1] = 0;
	  serline[strlen(serline)] = c;
	}
      else
	{
	  serline[0] = 0;
	}
    }
}

Generated by GNU Enscript 1.6.5.2.
Document Actions