mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-01 07:50:37 +00:00
Tweak M/X/E flag handling
The decision of how to handle indeterminate M/X flag values is made in StatusFlags. This provides consistent behavior throughout the app. This was being done for M/X but not for E. This change also renames the M/X tests, prefixing them with "Is" to emphasize that they are boolean rather than tri-state. There should be no change in behavior from this.
This commit is contained in:
parent
4e70edc90c
commit
bc15178a8e
@ -281,25 +281,25 @@ namespace Asm65 {
|
||||
// appropriately. So there's no ambiguity here even when there's ambiguity. We
|
||||
// make a similar statement about the E flag.
|
||||
if ((mods & OpDef.CycleMod.OneIfM0) != 0) {
|
||||
if (!flags.ShortM) {
|
||||
if (!flags.IsShortM) {
|
||||
cycles++;
|
||||
}
|
||||
mods &= ~OpDef.CycleMod.OneIfM0;
|
||||
}
|
||||
if ((mods & OpDef.CycleMod.TwoIfM0) != 0) {
|
||||
if (!flags.ShortM) {
|
||||
if (!flags.IsShortM) {
|
||||
cycles += 2;
|
||||
}
|
||||
mods &= ~OpDef.CycleMod.TwoIfM0;
|
||||
}
|
||||
if ((mods & OpDef.CycleMod.OneIfX0) != 0) {
|
||||
if (!flags.ShortX) {
|
||||
if (!flags.IsShortX) {
|
||||
cycles++;
|
||||
}
|
||||
mods &= ~OpDef.CycleMod.OneIfX0;
|
||||
}
|
||||
if ((mods & OpDef.CycleMod.OneIfE0) != 0) {
|
||||
if (flags.E == 0) {
|
||||
if (!flags.IsEmulationMode) {
|
||||
cycles++;
|
||||
}
|
||||
mods &= ~OpDef.CycleMod.OneIfE0;
|
||||
@ -323,7 +323,7 @@ namespace Asm65 {
|
||||
}
|
||||
}
|
||||
if ((mods & OpDef.CycleMod.OneIfBranchPage) != 0) {
|
||||
if (branchCrossesPage && flags.E != 0) {
|
||||
if (branchCrossesPage && flags.IsEmulationMode) {
|
||||
cycles++; // +1 unless we're in native mode on 65816
|
||||
}
|
||||
mods &= ~OpDef.CycleMod.OneIfBranchPage;
|
||||
|
@ -518,10 +518,10 @@ namespace Asm65 {
|
||||
return 4;
|
||||
|
||||
case AddressMode.ImmLongA:
|
||||
bool shortM = flags.ShortM;
|
||||
bool shortM = flags.IsShortM;
|
||||
return shortM ? 2 : 3;
|
||||
case AddressMode.ImmLongXY:
|
||||
bool shortX = flags.ShortX;
|
||||
bool shortX = flags.IsShortX;
|
||||
return shortX ? 2 : 3;
|
||||
|
||||
default:
|
||||
|
@ -132,6 +132,9 @@ namespace Asm65 {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// X (index register width) flag. For an unambiguous value, use IsShortX.
|
||||
/// </summary>
|
||||
public int X {
|
||||
get {
|
||||
return mState.GetBit((int)FlagBits.X);
|
||||
@ -149,6 +152,9 @@ namespace Asm65 {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// M (accumulator width) flag. For an unambiguous value, use IsShortM.
|
||||
/// </summary>
|
||||
public int M {
|
||||
get {
|
||||
return mState.GetBit((int)FlagBits.M);
|
||||
@ -200,6 +206,9 @@ namespace Asm65 {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// E (emulation) flag. For an unambiguous value, use IsEmulationMode.
|
||||
/// </summary>
|
||||
public int E {
|
||||
get {
|
||||
return mState.GetBit((int)FlagBits.E);
|
||||
@ -225,7 +234,10 @@ namespace Asm65 {
|
||||
/// Returns true if the current processor status flags are configured for a short
|
||||
/// (8-bit) accumulator.
|
||||
/// </summary>
|
||||
public bool ShortM {
|
||||
/// <remarks>
|
||||
/// This is where we decide how to treat ambiguous status flags.
|
||||
/// </remarks>
|
||||
public bool IsShortM {
|
||||
get {
|
||||
// E==1 --> true (we're in emulation mode)
|
||||
// E==0 || E==? : native / assumed native
|
||||
@ -239,13 +251,25 @@ namespace Asm65 {
|
||||
/// Returns true if the current processor status flags are configured for short
|
||||
/// (8-bit) X/Y registers.
|
||||
/// </summary>
|
||||
public bool ShortX {
|
||||
public bool IsShortX {
|
||||
get {
|
||||
// (same logic as ShortM)
|
||||
return (E == 1) || (X != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the current processor status flags are configured for execution
|
||||
/// in native mode.
|
||||
/// </summary>
|
||||
public bool IsEmulationMode {
|
||||
get {
|
||||
// E==1 : emulation --> true
|
||||
// E==0 || E==? : native / assumed native --> false
|
||||
return E == 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Access the value as a single integer. Used for serialization.
|
||||
/// </summary>
|
||||
|
@ -87,8 +87,8 @@ namespace SourceGen.AsmGen {
|
||||
// that in the ORG output handler.
|
||||
if (proj.CpuDef.HasEmuFlag) {
|
||||
StatusFlags curFlags = attr.StatusFlags;
|
||||
curFlags.M = attr.StatusFlags.ShortM ? 1 : 0;
|
||||
curFlags.X = attr.StatusFlags.ShortX ? 1 : 0;
|
||||
curFlags.M = attr.StatusFlags.IsShortM ? 1 : 0;
|
||||
curFlags.X = attr.StatusFlags.IsShortX ? 1 : 0;
|
||||
if (curFlags.M != prevFlags.M || curFlags.X != prevFlags.X) {
|
||||
// changed, output directive
|
||||
gen.OutputRegWidthDirective(offset, prevFlags.M, prevFlags.X,
|
||||
@ -355,7 +355,7 @@ namespace SourceGen.AsmGen {
|
||||
// Assemblers like Merlin32 try to be helpful and track SEP/REP, but they do the
|
||||
// wrong thing if we're in emulation mode. Force flags back to short.
|
||||
if (proj.CpuDef.HasEmuFlag && gen.Quirks.TracksSepRepNotEmu && op == OpDef.OpREP_Imm) {
|
||||
if ((operand & 0x30) != 0 && attr.StatusFlags.E == 1) {
|
||||
if ((operand & 0x30) != 0 && attr.StatusFlags.IsEmulationMode) {
|
||||
gen.OutputRegWidthDirective(offset, 0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
@ -928,8 +928,8 @@ namespace SourceGen {
|
||||
if (attr.IsInstructionStart) {
|
||||
prevFlags = attr.StatusFlags;
|
||||
// Apply the same tweak here that we do to curFlags below.
|
||||
prevFlags.M = attr.StatusFlags.ShortM ? 1 : 0;
|
||||
prevFlags.X = attr.StatusFlags.ShortX ? 1 : 0;
|
||||
prevFlags.M = attr.StatusFlags.IsShortM ? 1 : 0;
|
||||
prevFlags.X = attr.StatusFlags.IsShortX ? 1 : 0;
|
||||
Debug.WriteLine("GenerateLineList startOff=+" +
|
||||
startOffset.ToString("x6") + " using initial flags from +" +
|
||||
scanoff.ToString("x6") + ": " + prevFlags);
|
||||
@ -1017,8 +1017,8 @@ namespace SourceGen {
|
||||
// assembler something. So we tweak our local copy and propagate it.
|
||||
string operandStr = string.Empty;
|
||||
StatusFlags curFlags = attr.StatusFlags;
|
||||
curFlags.M = attr.StatusFlags.ShortM ? 1 : 0;
|
||||
curFlags.X = attr.StatusFlags.ShortX ? 1 : 0;
|
||||
curFlags.M = attr.StatusFlags.IsShortM ? 1 : 0;
|
||||
curFlags.X = attr.StatusFlags.IsShortX ? 1 : 0;
|
||||
if (curFlags.M != prevFlags.M) {
|
||||
operandStr = (curFlags.M == 0) ? "longm" : "shortm";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user