1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-09 20:29:32 +00:00
6502bench/SourceGen/WeakSymbolRef.cs
Andy McFadden 4e5c34f457 Binary includes
This adds a new data format option, "binary include", that takes a
filename operand.  When assembly sources are generated, the section
of file is replaced with an appropriate pseudo-op, and binary files
are generated that hold the file contents.  This is a convenient way
to remove large binary blobs, such as music or sound samples, that
aren't useful to have in text form in the sources.

Partial pathnames are allowed, so you can output a sound blob to
"sounds/blather.bin".  For safety reasons, we don't allow the files
to be created above the project directory, and existing files will
only be overwritten if they have a matching length (so you don't
accidentally stomp on your project file).

The files are not currently shown in the GenAsm dialog, which lets
you see a preview of the generated sources.  The hex dump tool
can do this for the (presumably rare) situations where it's useful.

A new regression test, 20300-binary-include, has been added.  The
pseudo-op name can be overridden on-screen in the settings.

We don't currently do anything new for text/HTML exports.  It might
be useful to generate an optional appendix with a hex dump of the
excised sections.

(issue #144)
2024-05-31 14:22:39 -07:00

124 lines
4.6 KiB
C#

/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Diagnostics;
namespace SourceGen {
/// <summary>
/// Weak reference to a symbol for use in an operand or data statement. The reference
/// is by name; if the symbol disappears or changes value, the reference can be ignored.
/// This also specifies which part of the numeric value is of interest, so we can reference
/// the high or low byte of a 16-bit value in (say) LDA #imm.
///
/// Instances are immutable.
/// </summary>
public class WeakSymbolRef {
/// <summary>
/// This identifies the part of the value that we're interested in. All values are
/// signed 32-bit integers.
/// </summary>
public enum Part {
// This indicates which byte we start with, useful for immediate operands
// and things like PEA. By popular convention, these are referred to as
// low, high, and bank.
//
// With 16-bit registers, Merlin 32 grabs the high *word*, while cc65's assembler
// grabs the high *byte*. One is a shift, the other is a byte select. We use
// low/high/bank just to mean position here.
//
// (Could make this orthogonal with a pair of bit fields, one for position and
// one for width, but there's really only three widths of interest (1, 2, 3 bytes)
// and that's defined by context.)
Unknown = 0,
Low, // LDA #label, LDA #<label
High, // LDA #>label
Bank, // LDA #^label
}
/// <summary>
/// If this is a local varaiable reference, what type is it.
/// </summary>
public enum LocalVariableType {
Unknown = 0,
NotVar,
DpAddr,
StackRelConst
}
/// <summary>
/// Label of symbol of interest.
/// </summary>
public string Label { get; private set; }
/// <summary>
/// Which part of the value we're referencing.
/// </summary>
public Part ValuePart { get; private set; }
/// <summary>
/// Is this a local variable reference, and if so, what type.
/// </summary>
public LocalVariableType VarType { get; private set; }
/// <summary>
/// True for local variable references.
/// </summary>
public bool IsVariable { get { return VarType != LocalVariableType.NotVar; } }
/// <summary>
/// Standard constructor.
/// </summary>
public WeakSymbolRef(string label, Part part) :
this(label, part, LocalVariableType.NotVar) { }
/// <summary>
/// Constructor for local variable table references.
/// </summary>
public WeakSymbolRef(string label, Part part, LocalVariableType varType) {
Debug.Assert(label != null);
Label = label;
ValuePart = part;
VarType = varType;
}
public static bool operator ==(WeakSymbolRef a, WeakSymbolRef b) {
if (ReferenceEquals(a, b)) {
return true; // same object, or both null
}
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) {
return false; // one is null
}
return Asm65.Label.LABEL_COMPARER.Equals(a.Label, b.Label) &&
a.ValuePart == b.ValuePart &&
a.VarType == b.VarType;
}
public static bool operator !=(WeakSymbolRef a, WeakSymbolRef b) {
return !(a == b);
}
public override bool Equals(object obj) {
return obj is WeakSymbolRef && this == (WeakSymbolRef)obj;
}
public override int GetHashCode() {
return Asm65.Label.ToNormal(Label).GetHashCode() ^ (int)ValuePart ^ (int)VarType;
}
public override string ToString() {
return "WeakSym: " + (IsVariable ? "var " : "") + Label + ":" + ValuePart;
}
}
}