Revision ca56e26f664017df4c8d99478337fbea6e4e741d authored by Ron Burkey on 21 March 2021, 23:51:57 UTC, committed by Ron Burkey on 21 March 2021, 23:51:57 UTC
1 parent f4ce9c0
Raw File
ParseEBANKEquals.c
/*
 * Copyright 2003,2004,2016 Ronald S. Burkey <info@sandroid.org>
 *
 * This file is part of yaAGC.
 *
 * yaAGC is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * yaAGC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with yaAGC; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Filename:    ParseEBANKEquals.c
 * Purpose:     Assembles the EBANK= pseudo-op.
 * History:     04/29/03 RSB    Began.
 *              07/23/04 RSB    Added SBANK.
 *              2011-05-17 JL   Split EBANK= and SBANK= parsers, and renamed.
 *              2016-10-21 RSB  Added code for processing the case of the
 *                              operand being a small literal number, sent
 *                              by Hartmuth Gutsche.
 */

#include "yaYUL.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>

//-------------------------------------------------------------------------
// 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)
    {
      if (blk2)
        {
          if (Value >= 0 && Value < 010)
            {
              // interpret as EBank number but let PseudoToSegmented do the job
              Value *= 0400; // create base POA of EBank
            }
        }
      if (Value < 010 || Value > 03777)
        {
          strcpy(OutRecord->ErrorMessage, "EBank address value out of range.");
          OutRecord->Fatal = 1;
          return (0);
        }

      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);
}

back to top