Example #1
0
int 
ChannelInputAGS (ags_t * State)
{
	//
	// This will need to accept data from the NASSP code and pass it through to Virtual
	// AGS.
	//
#if 0
  static int SocketInterlace = 0;
  int i, j, k;
  unsigned char c;
  Client_t *Client;
  int Mask;
  
  //We use SocketInterlace to slow down the number
  // of polls of the sockets.
  if (SocketInterlace > 0)
    SocketInterlace--;
  else
    {
      SocketInterlace = SocketInterlaceReload;
      for (i = 0, Client = Clients; i < MAX_CLIENTS; i++, Client++)
	if (Client->Socket != -1)
	  {
	    // We arbitrarily adopt the rule that we'll process at most one
	    // packet per client per instruction cycle.
	    for (j = Client->Size; j < 4; j++)
	      {
		k = recv (Client->Socket, &c, 1, 0);
		if (k == 0 || k == -1)
		  break;
		Client->Packet[Client->Size++] = c;
	      }
	    // Process a received packet.
	    if (Client->Size >= 4)
	      {
		int Type, Data;
		//printf ("Received from %d: %02X %02X %02X %02X\n",
		//	i, Client->Packet[0], Client->Packet[1],
		//	Client->Packet[2], Client->Packet[3]);
		if (!ParseIoPacketAGS (Client->Packet, &Type, &Data))
		  switch (Type)
		    {
		    case 000:		// PGNS theta integrator.
		    case 001:		// PGNS phi integrator.
		    case 002:		// PGNS psi integrator.
		      j = IO_2001 + Type;
		      if (Data == 0)
		        State->InputPorts[j] = 0;
		      else	
		        {
		          State->InputPorts[j] += SignExtendAGS (Data) * 4;
			  State->InputPorts[j] &= 0377774;
			}
		      break;
		    case 005:		// discrete input word 2.
		      // If the READ OUT or ENTR keys are active,
		      // we must intercept them and buffer the 
		      // associated data before letting the CPU
		      // know about it.
		      k = ((Data & 0777) << 9);
		      j = (Data & k) | ~k;
		      if (0 == (j & 04000))		// ENTR?
		        {
			  DedaBufferCount = 0;	// Prepare to collect data.
			  DedaBufferWanted = 9;
			  Data |= 04000;	// Reset the ENTR key.
			  // Request DEDA shift data.
			  ChannelOutputAGS (040, State->OutputPorts[IO_ODISCRETES] & ~010);
			}
		      else if (0 == (j & 02000))	// READ OUT?
		        {
			  DedaBufferCount = 0;	// Prepare to collect data.
			  DedaBufferWanted = 3;
			  Data |= 02000;	// Reset the READ OUT key.
			  // Request DEDA shift data.
			  ChannelOutputAGS (040, State->OutputPorts[IO_ODISCRETES] & ~010);
			}
		      // Yes, it is supposed to fall through here.		
		    case 004:		// Discrete input word 1.
		      j = IO_2020 + (Type - 4);
		      Mask = ((Data & 0777) << 9);
		      State->InputPorts[j] &= ~Mask;
		      State->InputPorts[j] |= (Data & Mask);
		      break;
		    case 007:		// DEDA.
		      // If we are buffering this input, we have to intercept it.
		      if (DedaBufferWanted)
		        {
			  if (DedaBufferCount < DedaBufferWanted)
			    {
			      DedaBuffer[DedaBufferCount++] = (Data & 0360000);  
			      if (DedaBufferCount < DedaBufferWanted)
			        {
				  // Request more DEDA shift data.
				  ChannelOutputAGS (040, State->OutputPorts[IO_ODISCRETES] & ~010);
				}
			      else
				{
				  // The data is all buffered.  We can tell the
				  // CPU that the ENTR or READ OUT key was pressed.
				  //printf ("Buffered from DEDA: CLR");
				  //for (j = 0; j < DedaBufferWanted; j++)
				  //  printf (" %02o", DedaBuffer[j] >> 13);
				  DedaBufferReadout = -1;
				  if (DedaBufferWanted == 3)
				    {
				      State->InputPorts[IO_2040] &= ~02000;	// READ OUT
				      //printf (" READOUT\n");
				    }
				  else
				    {
				      State->InputPorts[IO_2040] &= ~04000;	// ENTR.
				      //printf (" ENTR\n");
				    }
				}
			    }
			}
		      break;
		    case 011:		// delta-integral-q counter
		    case 012:		// delta-integral-r counter
		    case 013:		// delta-integral-p counter
		      j = IO_6002 + (Type - 011);
   	              State->InputPorts[j] += SignExtendAGS (Data) * 0100;
		      State->InputPorts[j] &= 0377700;
		      break;
		    case 014:		// delta-Vx counter.
		    case 015:		// delta-Vy counter.
		    case 016:		// delta-Vz counter.
		      j = IO_6020 + (Type - 014);
   	              State->InputPorts[j] += SignExtendAGS (Data) * 0100;
		      State->InputPorts[j] &= 0377700;
		      break;
		    case 017:		// downlink telemetry
		      State->InputPorts[IO_6200] = Data;
		      // Make the Downlink Telemetry Stop bit active.
		      State->InputPorts[IO_2020] &= ~0200000;
		      break;
		    }
		Client->Size = 0;
	      }
	  }
    }
#endif
  return (0);
}
Example #2
0
int
ChannelInput (agc_t *State)
{
  static int SocketInterlace = 0;
  int i, j, k;
  unsigned char c;
  Client_t *Client;
  int Channel, Value;

  //We use SocketInterlace to slow down the number
  // of polls of the sockets.
  if (SocketInterlace > 0)
    SocketInterlace--;
  else
    {
      SocketInterlace = SocketInterlaceReload;
      for (i = 0, Client = Clients; i < MAX_CLIENTS; i++, Client++)
	if (Client->Socket != -1)
	  {
	    // We arbitrarily adopt the rule that we'll process at most one
	    // packet per client per instruction cycle.
	    for (j = Client->Size; j < 4; j++)
	      {
		k = recv (Client->Socket, (char *) &c, 1, 0);
		if (k == 0 || k == -1)
		  break;
		// 20090318 RSB.  Added this filter for a little robustness,
		// but it shouldn't be needed.
		if (!(
		      (Signatures[j] == (c & 0xC0)) ||
		      (DebugDeda && (SignaturesAgs[j] == (c & 0xC0)))
		    )
		   )
		  {
		    Client->Size = 0;
		    if (0 != (c & 0xC0))
		      {
		        j = -1;
	                continue;
		      }
		    j = 0;
		  }
		Client->Packet[Client->Size++] = c;
	      }
	    // Process a received packet.
	    if (Client->Size >= 4)
	      {
		int uBit, Type, Data;
		//printf ("Received from %d: %02X %02X %02X %02X\n",
		//	i, Client->Packet[0], Client->Packet[1],
		//	Client->Packet[2], Client->Packet[3]);
		if (!ParseIoPacket (Client->Packet, &Channel, &Value, &uBit))
		  {
		    // Convert to AGC format (upper 15 bits).
		    Value &= 077777;
		    if (uBit)
		      {
			Client->ChannelMasks[Channel] = Value;
		      }
		    else if (Channel & 0x80)
		      {
		        // In this case we're dealing with a counter increment.
			// So increment the counter.
			//printf ("Channel=%02o Int=%o\n", Channel, Value);
			UnprogrammedIncrement (State, Channel, Value);
			Client->Size = 0;
			return (1);
		      }
		    else
		      {
			Value &= Client->ChannelMasks[Channel];
			Value |=
			  ReadIO (State,
				  Channel) & ~Client->ChannelMasks[Channel];
			WriteIO (State, Channel, Value);
			// If this is a keystroke from the DSKY, generate an interrupt req.
			if (Channel == 015)
			  State->InterruptRequests[5] = 1;
			// If this is on fictitious input channel 0173, then the data
			// should be placed in the INLINK counter register, and an
			// UPRUPT interrupt request should be set.
			else if (Channel == 0173)
			  {
			    State->Erasable[0][RegINLINK] = (Value & 077777);
			    State->InterruptRequests[7] = 1;
			  }
			// Fictitious registers for rotational hand controller (RHC).
			// Note that the RHC angles are not immediately used, but
			// merely squirreled away for later.  They won't actually
			// go into the counter registers until the RHC counters are
			// enabled and the data requested (bits 8,9 of channel 13).
			else if (Channel == 0166)
			  {
			    LastRhcPitch = Value;
			    ChannelOutput (State, Channel, Value);	// echo
			  }
			else if (Channel == 0167)
			  {
			    LastRhcYaw = Value;
			    ChannelOutput (State, Channel, Value);	// echo
			  }
			else if (Channel == 0170)
			  {
			    LastRhcRoll = Value;
			    ChannelOutput (State, Channel, Value);	// echo
			  }
			else if (Channel == 031)
			  {
			    static int LastInDetent = 040000;
			    int InDetent;
			    ChannelOutput (State, Channel, Value);
			    // If the RHC stick has moved out of detent,
			    // generate a RUPT10 interrupt.
			    InDetent = (040000 & Value);
			    if (LastInDetent && !InDetent)
			      State->InterruptRequests[10] = 1;
			    LastInDetent = InDetent;
			  }
			//---------------------------------------------------------------
			// For --debug-dsky mode.
			if (DebugDsky)
			  {
			    if (Channel == 032)
			      {
				// For DebugDsky purposes only, the PRO key is translated
				// to appear as the otherwise-fictitious KeyCode 0.
				if (0 != (Value & 020000))
				  {
				    Channel = 015;
				    Value = 0;
				  }
			      }
			    if (Channel == 015)
			      {
				int i, CurrentValue;
				Value &= 077777;
				for (i = 0; i < NumDebugRules; i++)
				  if (Value == DebugRules[i].KeyCode)
				    {
				      CurrentValue =
					CurrentChannelValues[DebugRules[i].
							     Channel];
				      switch (DebugRules[i].Logic)
					{
					case '=':
					  CurrentValue = DebugRules[i].Value;
					  break;
					case '|':
					  CurrentValue |= DebugRules[i].Value;
					  break;
					case '&':
					  CurrentValue &= DebugRules[i].Value;
					  break;
					case '^':
					  CurrentValue ^= DebugRules[i].Value;
					  break;
					default:
					  break;
					}
				      CurrentChannelValues[DebugRules[i].
							   Channel] =
					CurrentValue;
				      ChannelOutput (State,
						     DebugRules[i].Channel,
						     CurrentValue);
				    }
			      }
			    //if (Channel != 032 && Channel != 015)
			    //  WriteIO (State, Channel, Value);
			  }
			//---------------------------------------------------------------
		      }
		  }
		else if (DebugDeda && !ParseIoPacketAGS (Client->Packet, &Type, &Data))
		  {
		    // The following code is present only for debugging yaDEDA
		    // communications, and has no interesting purpose yaAGC-wise.
		    static unsigned char Buffer[9];
		    static int NumInBuffer = 0, NumWanted = 0, Collecting = 0;
		    static unsigned char Packet[4];
		    if (Type == 05 && (Data == 0777002 || Data == 0777004 ||
		        Data == 0777010 || Data == 0777020))
		      printf ("DEDA key release.\n");
		    else if (Collecting && Type == 07)
		      {
		        Buffer[NumInBuffer++] = Data >> 13;
			if (NumInBuffer < NumWanted)
			  send (Client->Socket, (const char *) Packet, 4, 0);
			else
			  {
			    int i;
			    Collecting = 0;
			    printf ("Received %d DEDA nibbles:", NumWanted);
			    for (i = 0; i < NumWanted; i++)
			      printf (" %1X", Buffer[i]);
			    printf ("\n");
			    if (NumWanted == 3)
			      {
			        if (!DedaQuiet)
			          DedaMonitor = 1;
				DedaAddress = Buffer[0] * 0100 + Buffer[1] * 010 + Buffer[2];
				DedaWhen = State->CycleCounter;
			      }
			  }
		      }
		    else if (Type == 05 && (Data == 0775002 || Data == 0773004))
		      {
		        NumInBuffer = 0;
			Collecting = 1;
			if (Data == 0775002)
			  {
		            printf ("Received DEDA READOUT.\n");
			    NumWanted = 3;
			  }
			else
			  {
		            printf ("Received DEDA ENTR.\n");
			    NumWanted = 9;
			  }
			FormIoPacketAGS (040, ~010, Packet);
			send (Client->Socket, (const char *) Packet, 4, 0);
		      }
		    else if (Type == 05 && Data == 0767010)
		      {
		        printf ("Received DEDA HOLD.\n");
			DedaMonitor = 0;
		      }
		    else if (Type == 05 && Data == 0757020)
		      {
		        printf ("Received DEDA CLR.\n");
			DedaMonitor = 0;
		      }
		    else
		      printf ("Unknown AGS packet %02X %02X %02X %02X\n",
		              Client->Packet[0], Client->Packet[1],
			      Client->Packet[2], Client->Packet[3]);
		  }
		Client->Size = 0;
	      }