Beispiel #1
0
//------------------------------------------------------------------------
// Return non-zero on unrecoverable error.
int ParseINDEX(ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
  Address_t Offset;
  int Value, i;
  //extern int KeepExtend;
  
  //KeepExtend = 1;
  OutRecord->Extend = InRecord->Extend;
  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->EBank = InRecord->EBank;
  OutRecord->SBank = InRecord->SBank;
  OutRecord->NumWords = 1;
  OutRecord->IndexValid = 1;

  i = GetOctOrDec(InRecord->Operand, &Value);
  if (!i)
    {
      if (*InRecord->Operand == '+' || *InRecord->Operand == '-')
	  IncPc(&InRecord->ProgramCounter, Value, &Offset);
      else
          PseudoToStruct(Value, &Offset);
	
       if (*InRecord->Mod1 != 0)
         {
	   i = GetOctOrDec(InRecord->Mod1, &Value);
	   if (!i)
	     OpcodeOffset = Value;
	 }
      
    DoIt:  
      if (!Offset.Address && !Offset.Constant)
        {
	  strcpy(OutRecord->ErrorMessage, "Index is not an address.");
	  Offset.SReg = 0;
	  OutRecord->Fatal = 1;
	}

      if ((InRecord->Extend && (Offset.SReg & ~07777)) || (!InRecord->Extend && (Offset.SReg & ~01777)))
        {
	  strcpy(OutRecord->ErrorMessage, "Index is out of range.");
	  Offset.SReg = 0;
	  OutRecord->Fatal = 1;
	}

      if (Offset.Constant)
        OutRecord->Words[0] = OPCODE + Offset.Value;
      else
        OutRecord->Words[0] = OPCODE + Offset.SReg;
    }
  else
    {
      // The operand is NOT a number.  Presumably, it's a symbol.
      i = FetchSymbolPlusOffset(&InRecord->ProgramCounter, InRecord->Operand, InRecord->Mod1, &Offset);
      if (!i)
        goto DoIt;
      sprintf(OutRecord->ErrorMessage, "Symbol \"%s\" undefined or offset bad", InRecord->Operand);
      OutRecord->Fatal = 1;
      OutRecord->Words[0] = OPCODE;
    }

  if (OutRecord->Words[0] == 050017)
    OutRecord->IndexValid = 0;

  return (0);  
}
Beispiel #2
0
int
ParseBBCON (ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
  Address_t Address, EBank;
  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;
  OutRecord->NumWords = 1;
  OutRecord->Words[0] = 0;
  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;
    }
  #ifdef ORIGINAL_SBANK_SURMISE
  if (!strcmp (InRecord->Operator, "BBCON*"))
    {
      OutRecord->Words[0] = 066100;
      OutRecord->Bank.CurrentSBank.Super = 1;
      return (0);
    }
  #endif
  i = GetOctOrDec (InRecord->Operand, &Value);
  if (!i && *InRecord->Mod1 == 0)
    {
      IncPc (&InRecord->ProgramCounter, Value, &Address);
    DoIt:  
      if (Address.Invalid)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination address not resolved.");
	  OutRecord->Fatal = 1;
	  return (0);
	}
      if (!Address.Address)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination is not a memory address.");
	  OutRecord->Fatal = 1;
	  return (0);
	}
      if (!Address.Fixed)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination is not in fixed memory.");
	  OutRecord->Fatal = 1;
	  return (0);
	}	
      if (Address.SReg < 02000 || Address.SReg > 07777)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination address out of range.");
	  OutRecord->Fatal = 1;
	  return (0);
	}	
      //printf ("PC=%o EB=%o,%o FB=%o SReg=%o Super=%o,%o ", 
      //        InRecord->ProgramCounter.SReg, Address.EB, InRecord->Bank.CurrentEBank.EB,
      //      Address.FB, Address.SReg,
      //      Address.Super, InRecord->Bank.CurrentSBank.Super);
      if (!Address.Banked)
        Address.Value = Address.SReg / 02000;
      else 
        Address.Value = Address.FB;
      EBank = InRecord->Bank.CurrentEBank;
      if (EBank.SReg >= 0 && EBank.SReg < 01400)
        EBank.EB = EBank.SReg / 0400;
      Address.Value = (Address.Value << 10) | EBank.EB;
      // Superbank processing.
      FixSuperbankBits (InRecord, &Address, &Address.Value);
      OutRecord->Words[0] = Address.Value;	
    }
  else
    {
      // The operand is NOT a number.  Presumably, it's a symbol.
      i = FetchSymbolPlusOffset (&InRecord->ProgramCounter, 
                                 InRecord->Operand, 
				 InRecord->Mod1, &Address);
      if (!i)
        goto DoIt;
      sprintf(OutRecord->ErrorMessage, "Symbol \"%s\" undefined or offset bad", InRecord->Operand);
      OutRecord->Fatal = 1;
    }
  return (0);  
}
Beispiel #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);
}
Beispiel #4
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);
}
Beispiel #5
0
int
ParseCADR (ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
  Address_t Address;
  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;
  OutRecord->NumWords = 1;
  OutRecord->Words[0] = 0;
  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 && *InRecord->Mod1 == 0)
    {
      IncPc (&InRecord->ProgramCounter, Value, &Address);
    DoIt:  
      if (Address.Invalid)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination address not resolved.");
	  OutRecord->Fatal = 1;
	  return (0);
	}
      if (!Address.Address)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination is not a memory address.");
	  OutRecord->Fatal = 1;
	  return (0);
	}
      if (!Address.Fixed || !Address.Banked)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination not in an F-bank.");
	  OutRecord->Fatal = 1;
	  return (0);
	}	
      // If this is a superbank, we massage a little more to get into the 15-bit
      // address range.
      if (Address.Super && Address.FB >= 030)
        Address.Value -= 010 * 02000;
      if (Address.Value < 010000 || Address.Value > 0107777)
        {
	  strcpy (OutRecord->ErrorMessage, "Destination address out of range.");
	  OutRecord->Fatal = 1;
	  return (0);
	}	
      OutRecord->Words[0] = Address.Value - 010000;	
    }
  else
    {
      // The operand is NOT a number.  Presumably, it's a symbol.
      i = FetchSymbolPlusOffset (&InRecord->ProgramCounter, 
                                 InRecord->Operand, 
				 InRecord->Mod1, &Address);
      if (!i)
        goto DoIt;
      sprintf(OutRecord->ErrorMessage, "Symbol \"%s\" undefined or offset bad", InRecord->Operand);
      OutRecord->Fatal = 1;
    }
  return (0);  
}
Beispiel #6
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);  
}