https://github.com/virtualagc/virtualagc
Revision 078c79d8734a9ed2860303a7c1662004284fe853 authored by Ron Burkey on 07 August 2022, 15:04:04 UTC, committed by Ron Burkey on 07 August 2022, 15:04:04 UTC
assembly listings from yaASM and yaLEMAP. Added some debugging messages to 'make install'. Tweaked debugging messages that VirtualAGC embeds in 'simulate'. Verified buildability in Mint 21, 20, 19, 17, and verified buildability using clang in Mint 17.
1 parent 6bb1acc
Tip revision: 078c79d8734a9ed2860303a7c1662004284fe853 authored by Ron Burkey on 07 August 2022, 15:04:04 UTC
Fixed a potential string-overflow bug in yaASM. Removed timestamps from
Fixed a potential string-overflow bug in yaASM. Removed timestamps from
Tip revision: 078c79d
IncPc.c
/*
Copyright 2003,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: IncPc.c
Purpose: Increments (or decrements) an Address_t structure, with
detection of out-of range. This is a more complicated
thing than it seems, because of the variety of different
types of memory bank. (Also, since the Address_t
structure can represent a constant rather than an address.)
History: 04/15/03 RSB Began.
08/18/16 RSB Some cross-my-finger-and-hope tweaks for
--block1.
*/
#include "yaYUL.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
//-------------------------------------------------------------------------
// Increment program counter by a certain amount.
// Sets the Overflow flag in the Address_t structure.
void IncPc(Address_t *OldPc, int Increment, Address_t *NewPc)
{
int i, j, Max, Min, BankIncrement;
// I have no theoretical basis for how to treat the case of Increment
// being very large (larger than a bank size), but there is a place
// in the Luminary source code where decrements of about 12000 (octal)
// are used. The lower 12 bits seem to be applied to SREG, whereas
// the upper 3 bits seem to be applied to the bank number.
if (Increment >= 0) {
BankIncrement = 7 & (Increment >> 12);
Increment &= 07777;
} else {
Increment = -Increment;
BankIncrement = -(7 & (Increment >> 12));
Increment = -(07777 & Increment);
}
// Get a good starting point for the calculation.
*NewPc = *OldPc;
// If the value is invalid---not yet assigned---then adding to it makes
// no sense.
if (NewPc->Invalid)
return;
// Okay, add to the existing Value. This is something that ALWAYS works.
// (Only overflowing 32-bit arithmetic could make it fail, but since
// all possible starting values and increments are 15-bit or less,
// overflowing 32-bit arithmetic would be a real feat!
//NewPc->Value += Increment;
// Convert constants (which are presumably pseudo-addresses) to real
// addresses.
if (NewPc->Constant) {
// ... except we do want to check that the constant is in range.
//if (NewPc->Value < -16383 || NewPc->Value > 32767)
// NewPc->Overflow = 1;
if (NewPc->Value < 0)
return;
else if (NewPc->Value < 01400) {
NewPc->Constant = 0;
NewPc->Address = 1;
NewPc->Erasable = 1;
NewPc->Fixed = 0;
NewPc->Banked = 0;
NewPc->Unbanked = 1;
NewPc->EB = 0;
NewPc->FB = 0;
#ifdef YAYUL_TRACE
printf("*** IncPc (%d): clearing superbank...\n", __LINE__);
#endif
NewPc->Super = 0;
NewPc->SReg = NewPc->Value;
} else
return;
}
// Okey-smokey, the "address" is really an address. If it has previously
// overflowed, there's no particular reason to continue.
if (NewPc->Overflow)
return;
// Compute the new S-register value (in the absence of overflow).
i = (j = NewPc->SReg) + Increment;
NewPc->SReg = i;
if (NewPc->Erasable && NewPc->Banked)
NewPc->EB += BankIncrement;
else if (NewPc->Fixed && NewPc->Banked)
NewPc->FB += BankIncrement;
// Okay, here's some workaround code for the weird construct
// TC FixedMemoryLabel -LargeOffset
// taking a location in fixed memory down to a location in erasable.
// Don't blame me!
if (NewPc->Fixed && BankIncrement != 0 && NewPc->FB == 0) {
NewPc->Constant = 0;
NewPc->Address = 1;
NewPc->Erasable = 1;
NewPc->Fixed = 0;
NewPc->Banked = 0;
NewPc->Unbanked = 1;
NewPc->EB = 0;
NewPc->FB = 0;
#ifdef YAYUL_TRACE
//printf("--- IncPc (%d): clearing superbank...\n", __LINE__);
#endif
NewPc->Super = 0;
}
// Determine the appropriate SReg ranges for this memory region.
// The address will be either banked or unbanked, and either in fixed
// memory or erasable memory. So, there are four possible combos.
if (NewPc->Erasable) {
if (NewPc->Unbanked) {
Min = 0;
Max = Block1 ? 01777 : 01377;
} else if (!Block1 && NewPc->Banked) {
Min = 01400;
Max = 01777;
NewPc->EB += BankIncrement;
} else
goto ImplementationError;
} else if (NewPc->Fixed) {
if (NewPc->Banked) {
Min = Block1 ? 06000 : 02000;
Max = Block1 ? 07777 : 03777;
NewPc->FB += BankIncrement;
} else if (NewPc->Unbanked) {
Min = Block1 ? 02000 : 04000;
Max = 07777;
} else
goto ImplementationError;
} else
goto ImplementationError;
// Did the new S-register value go out of range for the memory region?
if (i < Min) {
NewPc->Overflow = 1;
NewPc->SReg = Min;
} else if (i > Max) {
NewPc->Overflow = 1;
NewPc->SReg = Max;
}
// Back-convert to get a pseudo-address.
if (NewPc->Unbanked)
NewPc->Value = NewPc->SReg;
else if (NewPc->Erasable) {
NewPc->Value = (NewPc->SReg - 01400) + 0400 * NewPc->EB;
}
else if (NewPc->Fixed) {
NewPc->Value = 010000 + (NewPc->SReg - 02000) + 02000 * NewPc->FB;
if (NewPc->Super && NewPc->FB >= 030)
NewPc->Value += 010 * 02000;
} else
goto ImplementationError;
return;
ImplementationError:
// Can't occur, but I give it a good pinch if it does!
NewPc->Invalid = 1;
}
Computing file changes ...