int FetchSymbolPlusOffset (Address_t *pc, char *Operand, char *Mod1, Address_t *Value) { Symbol_t *Symbol; int i, Offset; i = GetOctOrDec (Operand, &Offset); if (!i) { IncPc (pc, Offset, Value); return (0); } Value->Invalid = 1; Symbol = GetSymbol (Operand); if (Symbol == NULL) return (1); *Value = Symbol->Value; i = GetOctOrDec (Mod1, &Offset); if (!i) { //IncPc (&Symbol->Value, Offset, Value); OpcodeOffset = Offset; // I'm not sure how to treat very big offsets. Empirically, this works. if (OpcodeOffset >= 0) OpcodeOffset &= 07777; else OpcodeOffset = -(07777 & -OpcodeOffset); } return (0); }
int ParseBLOCK(ParseInput_t *InRecord, ParseOutput_t *OutRecord) { int Value, i; 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->Index = 0; } i = GetOctOrDec(InRecord->Operand, &Value); if (!i) { if (Value == 0 || Value == 2 || Value == 3) { Value = GetBankCount(Value) + Value * 02000; OutRecord->ProgramCounter = (const Address_t) { 0 }; OutRecord->ProgramCounter.Address = 1; OutRecord->ProgramCounter.SReg = Value; if (Value == 0) OutRecord->ProgramCounter.Erasable = 1; else OutRecord->ProgramCounter.Fixed = 1; OutRecord->ProgramCounter.Unbanked = 1; OutRecord->ProgramCounter.Value = Value; if (Value == 0) OutRecord->EBank.current = OutRecord->ProgramCounter; } else { strcpy(OutRecord->ErrorMessage, "BLOCK operand must be 0, 2, or 3."); OutRecord->ProgramCounter = (const Address_t) { 0 }; OutRecord->ProgramCounter.Invalid = 1; } } else {
//------------------------------------------------------------------------ // 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); }
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); }
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); }
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); }
//------------------------------------------------------------------------- // 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); }
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); }
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); }
int ParseBANK(ParseInput_t *InRecord, ParseOutput_t *OutRecord) { int Value, i; // Pass EXTEND through. OutRecord->Extend = InRecord->Extend; if (InRecord->IndexValid) { strcpy(OutRecord->ErrorMessage, "Illegally preceded by INDEX."); OutRecord->Fatal = 1; OutRecord->Index = 0; } // The case of no Operand has a special meaning. It means simply to // advance the program counter by however many words have already // been used in the current bank. It would be used after a SETLOC. if (!*InRecord->Operand) { OutRecord->ProgramCounter = InRecord->ProgramCounter; if (OutRecord->ProgramCounter.Invalid) return (0); if (!OutRecord->ProgramCounter.Address || !OutRecord->ProgramCounter.Fixed) { strcpy(OutRecord->ErrorMessage, "Works only for fixed-memory."); OutRecord->Fatal = 1; return (0); } if (OutRecord->ProgramCounter.Banked) { i = OutRecord->ProgramCounter.FB + 010 * OutRecord->ProgramCounter.Super; OutRecord->ProgramCounter.SReg = 02000 + UsedInBank[i]; OutRecord->ProgramCounter.Value = 010000 + i * 02000 + UsedInBank[i]; } else if (OutRecord->ProgramCounter.Value >= 04000 && OutRecord->ProgramCounter.Value <= 05777) { OutRecord->ProgramCounter.SReg = 04000 + UsedInBank[2]; OutRecord->ProgramCounter.Value = OutRecord->ProgramCounter.SReg; } else if (OutRecord->ProgramCounter.Value >= 06000 && OutRecord->ProgramCounter.Value <= 07777) { OutRecord->ProgramCounter.SReg = 06000 + UsedInBank[3]; OutRecord->ProgramCounter.Value = OutRecord->ProgramCounter.SReg; } #ifdef YAYUL_TRACE PrintTrace(InRecord, OutRecord); #endif return (0); } // Here's where we assume that an Operand field exists. i = GetOctOrDec(InRecord->Operand, &Value); if (!i) { if (Value >= 0 && Value <= 043) { OutRecord->ProgramCounter = (const Address_t) { 0 }; OutRecord->ProgramCounter.Address = 1; OutRecord->ProgramCounter.SReg = 02000; OutRecord->ProgramCounter.Fixed = 1; OutRecord->ProgramCounter.Banked = 1; if (Value >= 040) { OutRecord->ProgramCounter.Super = 1; OutRecord->ProgramCounter.FB = Value - 010; } else { OutRecord->ProgramCounter.Super = 0; OutRecord->ProgramCounter.FB = Value; } if (Block1 && Value >= 0 && Value <= 2) { OutRecord->ProgramCounter.Value = 02000 * Value; OutRecord->ProgramCounter.SReg = 02000 * Value; OutRecord->ProgramCounter.Banked = 0; OutRecord->ProgramCounter.Unbanked = 1; } else if (Block1) { OutRecord->ProgramCounter.Value = 06000; OutRecord->ProgramCounter.SReg = 06000; } else if (Value == 2 || Value == 3) OutRecord->ProgramCounter.Value = Value * 02000; else OutRecord->ProgramCounter.Value = 010000 + Value * 02000; OutRecord->ProgramCounter.Value += UsedInBank[Value]; OutRecord->ProgramCounter.SReg += UsedInBank[Value]; } else { strcpy(OutRecord->ErrorMessage, "BANK operand range is 00 to 43."); OutRecord->Fatal = 1; OutRecord->ProgramCounter = (const Address_t) { 0 }; OutRecord->ProgramCounter.Invalid = 1; } } else {