Exemplo n.º 1
0
int 
ParseERASE (ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
  int Value, i;
  IncPc (&InRecord->ProgramCounter, 1, &OutRecord->ProgramCounter);
  if (!OutRecord->ProgramCounter.Invalid && OutRecord->ProgramCounter.Overflow)
    {
      strcpy (OutRecord->ErrorMessage, "Next code may overflow storage.");
      OutRecord->Warning = 1;
    }
  OutRecord->Bank = InRecord->Bank;
  if (InRecord->Extend && !InRecord->IndexValid)
    {
      strcpy (OutRecord->ErrorMessage, "Illegally preceded by EXTEND.");
      OutRecord->Fatal = 1;
      OutRecord->Extend = 0;
    }
  if (InRecord->IndexValid)
    {
      strcpy (OutRecord->ErrorMessage, "Illegally preceded by INDEX.");
      OutRecord->Fatal = 1;
      OutRecord->IndexValid = 0;
    }
  i = GetOctOrDec (InRecord->Operand, &Value);
  if (!i)
    {
      if (Value < 0)
        {
	  strcpy (OutRecord->ErrorMessage, "Address increment is negative.");
	  OutRecord->Warning = 1;
	}	
      else
        {
	  // There are really two cases here.  Normally, the operand is
	  // simply a number, and that's the end of it.  But it's also
	  // possible that Mod1 is "-", and Mod2 is another number, in 
	  // which case we want to allocate a range.
	  if (!strcmp (InRecord->Mod1, "-"))
	    {
#if 0
	      // This is the range case, "ERASE n - m".
	      i = GetOctOrDec (InRecord->Mod2, &Value2);
	      Value2++;
	      if (i)
	        {
		  strcpy (OutRecord->ErrorMessage, "End of range missing or illegal.");
		  OutRecord->Fatal = 1;
		}
	      else if (Value2 <= Value)
	        {
		  strcpy (OutRecord->ErrorMessage, "Ending address precedes starting address.");
		  OutRecord->Fatal = 1;
		}	
	      else
	        {
		  ParseOutput_t Dummy = { { 0 } }, Dummy2 = { { 0 } };
		  PseudoToSegmented (Value, &Dummy);
		  PseudoToSegmented (Value2, &Dummy2);
		  if (Dummy.Fatal || Dummy.Warning || Dummy2.Fatal || Dummy2.Warning
		      || Dummy.ProgramCounter.Invalid || !Dummy.ProgramCounter.Erasable
		      || Dummy2.ProgramCounter.Invalid || !Dummy2.ProgramCounter.Erasable
		      || Dummy.ProgramCounter.Banked != Dummy2.ProgramCounter.Banked
		      || Dummy.ProgramCounter.EB != Dummy2.ProgramCounter.EB)
		    {
		      strcpy (OutRecord->ErrorMessage, "May span bank boundary.");
		      OutRecord->Warning = 1;
		    }
		  InRecord->ProgramCounter = Dummy.ProgramCounter;
		  OutRecord->ProgramCounter = Dummy2.ProgramCounter;
		}
#else // 0
  		  char Mod1[1 + MAX_LINE_LENGTH], Mod2[1 + MAX_LINE_LENGTH];
		  strcpy (Mod1, InRecord->Mod1);
		  strcpy (Mod2, InRecord->Mod2);
		  strcpy (InRecord->Mod1, "");
		  strcpy (InRecord->Mod2, "");  
		  strcpy (InRecord->Operator, "EQUALS");            
		  ParseEQUALS (InRecord, OutRecord);
		  strcpy (InRecord->Mod1, Mod1);
		  strcpy (InRecord->Mod2, Mod2);
		  strcpy (InRecord->Operator, "ERASE");
#endif // 0
	    }
	  else
	    {  
	      // This is the normal case, "ERASE n".
	      if (0 != *InRecord->Mod1 && !OutRecord->Fatal)
	        {
		  strcpy (OutRecord->ErrorMessage, "Extra fields are present.");
		  OutRecord->Warning = 1;
		}
	      IncPc (&InRecord->ProgramCounter, 1 + Value, &OutRecord->ProgramCounter);
	      if (!OutRecord->ProgramCounter.Invalid)
		{
		  if (!OutRecord->ProgramCounter.Erasable)
		    {
		      strcpy (OutRecord->ErrorMessage, "Not in erasable memory.");
		      OutRecord->Fatal = 1;
		    }
		  else if (OutRecord->ProgramCounter.Overflow)
		    {
		      strcpy (OutRecord->ErrorMessage, "May overflow memory bank.");
		      OutRecord->Warning = 1;
		    }
		}
	    }
	}
    }
  else if (0 != *InRecord->Operand)
    {
      // Note that if the Operand field is simply missing, it's legal.
      strcpy (OutRecord->ErrorMessage, "Illegal number.");
      OutRecord->Fatal = 1;
    }  
  return (0);  
}
Exemplo n.º 2
0
//-------------------------------------------------------------------------
// Returns non-zero on unrecoverable error.
int ParseEBANKEquals(ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
    ParseOutput_t Dummy;
    Address_t Address;
    int Value, i;

    OutRecord->Extend = InRecord->Extend;
    OutRecord->IndexValid = InRecord->IndexValid;
    OutRecord->EBank = InRecord->EBank;
    OutRecord->SBank = InRecord->SBank;
    OutRecord->NumWords = 0;
    OutRecord->ProgramCounter = InRecord->ProgramCounter;

    if (*InRecord->Mod1) {
        strcpy(OutRecord->ErrorMessage, "Extra fields.");
        OutRecord->Warning = 1;
    }

    i = GetOctOrDec(InRecord->Operand, &Value);
    if (!i) {
        PseudoToSegmented(Value, &Dummy);
        Address = Dummy.ProgramCounter;

        DoIt:
        if (Address.Invalid) {
            strcpy(OutRecord->ErrorMessage, "Destination address not resolved.");
            OutRecord->Fatal = 1;
            return (0);
        }

        if (!Address.Erasable) {
            strcpy(OutRecord->ErrorMessage, "Destination not erasable.");
            OutRecord->Fatal = 1;
            return (0);
        }

        if (Address.SReg < 0 || Address.SReg > 01777) {
            strcpy(OutRecord->ErrorMessage, "Destination address out of range.");
            OutRecord->Fatal = 1;
            return (0);
        }

        OutRecord->EBank.last = OutRecord->EBank.current;
        OutRecord->EBank.current = Address;
        OutRecord->EBank.oneshotPending = 1;
        OutRecord->LabelValue = Address;
        OutRecord->LabelValueValid = 1;
    } else {
        // The operand is NOT a number.  Presumably, it's a symbol.
        i = FetchSymbolPlusOffset(&InRecord->ProgramCounter, InRecord->Operand, "", &Address);
        if (!i) {
            IncPc(&Address, OpcodeOffset, &Address);
            goto DoIt;
        }

        sprintf(OutRecord->ErrorMessage, "Symbol \"%s\" undefined or offset bad", InRecord->Operand);
        OutRecord->Fatal = 1;
    }

#ifdef YAYUL_TRACE
    PrintTrace(InRecord, OutRecord);
#endif

    return (0);
}
Exemplo n.º 3
0
int
ParseEQUALS (ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
    Address_t LabelValue = { 1 };
    int Value, i;
    OutRecord->ProgramCounter = InRecord->ProgramCounter;
    OutRecord->Bank = InRecord->Bank;
    OutRecord->LabelValue.Invalid = 1;
    OutRecord->NumWords = 0;
    OutRecord->Equals = 1;
    // As a special case, it sometimes happens that the label is empty.
    // I *believe* that this is done only for documentation purposes, and
    // has no other effect.
    if (*InRecord->Label == 0)
    {
        OutRecord->LabelValueValid = 0;
        return (0);
    }
    // As another special case, there is sometimes no operand.  *That* means
    // that the current program counter is the value.
    if (*InRecord->Operand == 0 && *InRecord->Mod1 == 0)
    {
        // JMS: Even though it is assigned the program counter as the current
        // value, it is still just a constant
        //EditSymbol (InRecord->Label, &InRecord->ProgramCounter);
        EditSymbolNew (InRecord->Label, &InRecord->ProgramCounter, SYMBOL_CONSTANT,
                       CurrentFilename, CurrentLineInFile);
        OutRecord->LabelValue = InRecord->ProgramCounter;
        return (0);
    }
    // Next, it may be that the operand is simply a number.  If so, then
    // we're talking about a simple constant.
    i = GetOctOrDec (InRecord->Operand, &Value);
    if (i)
    {
        // The operand is NOT a number.  Presumably, it's a symbol.
        i = FetchSymbolPlusOffset (&InRecord->ProgramCounter,
                                   InRecord->Operand,
                                   InRecord->Mod1, &LabelValue);
        if (i)
        {
            sprintf(OutRecord->ErrorMessage, "Symbol \"%s\" undefined or offset bad", InRecord->Operand);
            OutRecord->Fatal = 1;
            return (0);
        }
#if 0
        if (!i)
        {
            LabelValue = CONSTANT (0);
            LabelValue.Value = Value;
            EditSymbol (InRecord->Label, &LabelValue);
        }
#endif
        if (OpcodeOffset)
        {
            if (LabelValue.Constant)
            {
                LabelValue.Value += OpcodeOffset;
            }
            else
                IncPc (&LabelValue, OpcodeOffset, &LabelValue);
        }

        // JMS: This is just a constant to add to the symbol table
        //EditSymbol (InRecord->Label, &LabelValue);
        EditSymbolNew (InRecord->Label, &LabelValue, SYMBOL_CONSTANT,
                       CurrentFilename, CurrentLineInFile);
        OutRecord->LabelValueValid = 1;
    }
    else
    {
        ParseOutput_t TempOutput;
        if (*InRecord->Operand == '+' || *InRecord->Operand == '-')
        {
            IncPc (&InRecord->ProgramCounter, Value, &LabelValue);
        }
        else
        {
            if (Value < -16383 || Value > 32767)
            {
                strcpy (OutRecord->ErrorMessage, "Value out of range---truncating");
                OutRecord->Warning = 1;
                if (Value < -16383)
                    Value = -16383;
                else if (Value > 32767)
                    Value = 32767;
            }
            LabelValue.Invalid = 0;
            LabelValue.Constant = 1;
            LabelValue.Value = Value;
            PseudoToSegmented (Value, &TempOutput);
        }

        // JMS: This is just a constant to add to the symbol table
        //EditSymbol (InRecord->Label, &LabelValue /*&TempOutput.ProgramCounter*/);
        EditSymbolNew (InRecord->Label, &LabelValue, SYMBOL_CONSTANT,
                       CurrentFilename, CurrentLineInFile);
    }
    OutRecord->LabelValue = LabelValue;
    return (0);
}
Exemplo n.º 4
0
int ParseEQUALS(ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
  Address_t LabelValue = { 1 };
  int Value, i;

  OutRecord->ProgramCounter = InRecord->ProgramCounter;
  OutRecord->EBank = InRecord->EBank;
  OutRecord->SBank = InRecord->SBank;
  OutRecord->LabelValue.Invalid = 1;
  OutRecord->NumWords = 0;
  OutRecord->Equals = 1;

  // As a special case, it sometimes happens that the label is empty.
  // I *believe* that this is done only for documentation purposes, and
  // has no other effect.
  if (*InRecord->Label == 0)
    {
      OutRecord->LabelValueValid = 0;
      return (0);
    }

  // As another special case, there is sometimes no operand.  *That* means
  // that the current program counter is the value.  
  if (*InRecord->Operand == 0 && *InRecord->Mod1 == 0)
    {
      EditSymbolNew(InRecord->Label, &InRecord->ProgramCounter, SYMBOL_CONSTANT,
                    CurrentFilename, CurrentLineInFile);
      OutRecord->LabelValue = InRecord->ProgramCounter;
      return (0);
    }

  i = GetOctOrDec(InRecord->Operand, &Value);
  if (i)
    {
      // The operand is NOT a number.  Presumably, it's a symbol.
      if (!strcmp(InRecord->Mod1, "+") || !strcmp(InRecord->Mod1, "-"))
      {
          // Handle the case of whitespace between +/- and the actual offset. 
          if (*InRecord->Mod2 != 0)
          {
              char mod[1 + MAX_LINE_LENGTH];

              strcpy(mod, InRecord->Mod1);
              strcat(mod, InRecord->Mod2);
              i = FetchSymbolPlusOffset(&InRecord->ProgramCounter, 
                                        InRecord->Operand, 
                                        mod, 
                                        &LabelValue);
          }
          else
          {
              sprintf(OutRecord->ErrorMessage, "Syntax error, invalid offset specified");
              OutRecord->Fatal = 1;
              return(0);
          }
      }
      else
      {
          i = FetchSymbolPlusOffset(&InRecord->ProgramCounter, 
                                    InRecord->Operand, 
                                    InRecord->Mod1, 
                                    &LabelValue);
      }

      if (i)
      {
          sprintf(OutRecord->ErrorMessage, "Symbol \"%s\" undefined or offset bad", InRecord->Operand);
          OutRecord->Fatal = 1;
          return(0);
      }

      if (OpcodeOffset)
        {
          if (LabelValue.Constant)
            {
              LabelValue.Value += OpcodeOffset;
            }
          else
            IncPc(&LabelValue, OpcodeOffset, &LabelValue);
        }

      EditSymbolNew(InRecord->Label, &LabelValue, SYMBOL_CONSTANT, CurrentFilename, CurrentLineInFile);
      OutRecord->LabelValueValid = 1;
    }
  else
    {
      // Next, it may be that the operand is simply a number.  If so, then
      // we're talking about a simple constant.  

      ParseOutput_t TempOutput;

      if (*InRecord->Operand == '+' || *InRecord->Operand == '-')
        {
          IncPc(&InRecord->ProgramCounter, Value, &LabelValue);
        }
      else
        {
          if (Value < -16383 || Value > 32767)
            {
              strcpy(OutRecord->ErrorMessage, "Value out of range---truncating");
              OutRecord->Warning = 1;
              if (Value < -16383)
                Value = -16383;
              else if (Value > 32767)
                Value = 32767;  
            }

          LabelValue.Invalid = 0;
          LabelValue.Constant = 1;
          LabelValue.Value = Value;

          PseudoToSegmented(Value, &TempOutput);

          if (!TempOutput.ProgramCounter.Invalid)
            {
              LabelValue = TempOutput.ProgramCounter;
              if (!strcmp(InRecord->Operator, "ERASE"))
                {
                  // Special case. This is to handle "ERASE start - end" constructs, 
                  // which should not be tagged as constants.
                  LabelValue.Constant = 0;
                }
              else
                {
                  // Otherwise mark it as a constant as well.
                  LabelValue.Constant = 1;
                }
            }
        }

      EditSymbolNew(InRecord->Label, &LabelValue, SYMBOL_CONSTANT, CurrentFilename, CurrentLineInFile);
    }

  OutRecord->LabelValue = LabelValue;

  return (0);  
}