Revision b8b57e269c64f67bb4bbd1539da9c1d863077741 authored by Mike Stewart on 07 August 2021, 22:47:38 UTC, committed by Mike Stewart on 07 August 2021, 22:47:38 UTC
1 parent feabfcc
ParseSBANKEquals.c
/*
* Copyright 2003,2004 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: ParseSBANKEquals.c
* Purpose: Assembles the SBANK= pseudo-op.
* Mod history: 04/29/03 RSB Began.
* 07/23/04 RSB Added SBANK.
* 2011-05-17 JL Split EBANK= and SBANK= parsers, and renamed.
* 2016-11-03 RSB Using SBANK= without an operand now "unestablishes"
* the superbit setting, which results in things like
* BBCON and 2CADR being assembled to different (though
* operationally identical) octals. There should be
* no reason to have to do that, as far as I can see
* from YUL's program comments, but I needed it as a
* workaround for Sunburst 120.
* 2017-06-17 MAS Refactored the SBANK= logic. Once established,
* the SBank remains established. It is also now
* tracked simply as a superbank number, as in YUL.
*/
#include "yaYUL.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
int ParseSBANKEquals(ParseInput_t *InRecord, ParseOutput_t *OutRecord)
{
ParseOutput_t Dummy;
Address_t Address;
int Value, i;
OutRecord->EBank = InRecord->EBank;
OutRecord->SBank = InRecord->SBank;
OutRecord->NumWords = 0;
OutRecord->ProgramCounter = InRecord->ProgramCounter;
if (!*InRecord->Operand)
{
return (0);
}
if (*InRecord->Mod1) {
strcpy(OutRecord->ErrorMessage, "Extra fields.");
OutRecord->Warning = 1;
}
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) {
PseudoToSegmented(Value, &Dummy);
Address = Dummy.ProgramCounter;
DoIt:
if (Address.Invalid) {
strcpy(OutRecord->ErrorMessage, "Destination address not resolved.");
OutRecord->Fatal = 1;
return (0);
}
if (!Address.Fixed) {
strcpy(OutRecord->ErrorMessage, "Destination not in fixed memory.");
OutRecord->Fatal = 1;
return (0);
}
if (Address.SReg < 02000 || Address.SReg > 03777) {
strcpy(OutRecord->ErrorMessage, "Destination address out of range.");
OutRecord->Fatal = 1;
return (0);
}
if (Address.FB >= 030 && Address.FB <= 037) {
// Back up the current SBank in case of a oneshot.
OutRecord->SBank.last = OutRecord->SBank.current;
// Determine if the target address is in superbank 3 or 4.
if (Address.Super) {
OutRecord->SBank.current = 4;
} else {
OutRecord->SBank.current = 3;
}
} else {
strcpy(OutRecord->ErrorMessage, "Destination address not in superbank.");
OutRecord->SBank.current = 0;
OutRecord->Fatal = 1;
return (0);
}
OutRecord->SBank.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;
}
strcpy(OutRecord->ErrorMessage, "Symbol undefined or offset bad");
OutRecord->Fatal = 1;
}
#ifdef YAYUL_TRACE
PrintTrace(InRecord, OutRecord);
#endif
return (0);
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...