1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-07-07 22:28:57 +00:00

Progress toward 64tass support

Most tests pass, but 2007-labels-and-symbols fails because the
expressions recognized by 64tass don't match up with either of the
other assemblers.

This is currently using a workaround for the local label syntax.
64tass uses '_' as the prefix, which is unfortunate since SourceGen
explicitly allowed underscores in labels.  (So does 64tass for that
matter, but it treats labels specially when the '_' comes first.)
We will need to rename any non-local user labels that start with '_'.

(issue #16)
This commit is contained in:
Andy McFadden 2018-10-23 16:06:29 -07:00
parent eec37b684e
commit f7e5cf2f45
32 changed files with 3684 additions and 13 deletions

View File

@ -582,7 +582,7 @@ namespace Asm65 {
case AddressMode.StackRTI:
case AddressMode.StackRTL:
case AddressMode.StackRTS:
fmt = "";
fmt = string.Empty;
break;
case AddressMode.StackRel:
fmt = "{0}," + mSregChar;

View File

@ -30,7 +30,7 @@ namespace SourceGen.AsmGen {
/// Generate source code compatible with the cc65 assembler (https://github.com/cc65/cc65).
/// </summary>
public class GenCc65 : IGenerator {
private const string ASM_FILE_SUFFIX = "_cc65.S";
private const string ASM_FILE_SUFFIX = "_cc65.S"; // must start with underscore
private const int MAX_OPERAND_LEN = 64;
// IGenerator
@ -305,6 +305,7 @@ namespace SourceGen.AsmGen {
}
return newValue;
}
// Unmapped values include DOP, TOP, and the alternate SBC. Output hex.
return null;
} else {
return string.Empty;
@ -461,7 +462,7 @@ namespace SourceGen.AsmGen {
}
// IGenerator
public void OutputOrgDirective(int address) {
public void OutputOrgDirective(int offset, int address) {
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective),
SourceFormatter.FormatHexValue(address, 4), string.Empty);
}

View File

@ -31,7 +31,7 @@ namespace SourceGen.AsmGen {
/// (https://www.brutaldeluxe.fr/products/crossdevtools/merlin/).
/// </summary>
public class GenMerlin32 : IGenerator {
private const string ASM_FILE_SUFFIX = "_Merlin32.S";
private const string ASM_FILE_SUFFIX = "_Merlin32.S"; // must start with underscore
private const int MAX_OPERAND_LEN = 64;
// IGenerator
@ -364,7 +364,7 @@ namespace SourceGen.AsmGen {
}
// IGenerator
public void OutputOrgDirective(int address) {
public void OutputOrgDirective(int offset, int address) {
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective),
SourceFormatter.FormatHexValue(address, 4), string.Empty);
}

View File

@ -0,0 +1,780 @@
/*
* Copyright 2018 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.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using Asm65;
using CommonUtil;
namespace SourceGen.AsmGen {
#region IGenerator
/// <summary>
/// Generate source code compatible with the 64tass assembler
/// (https://sourceforge.net/projects/tass64/).
///
/// The assembler is officially called "64tass", but it's sometimes written "tass64" because
/// in some cases you can't start an identifier with a number.
///
/// We need to deal with a couple of unusual aspects:
/// (1) The prefix for a local label is '_', which is generally a legal character. So
/// if somebody creates a label with a leading '_', and it's not actually local, we have
/// to "de-local" it somehow.
/// (2) By default, labels are handled in a case-insensitive fashion, which is extremely
/// rare for programming languages. Case sensitivity can be enabled with the "-C" flag.
/// Anybody who wants to assemble the generated code will need to be aware of this.
/// </summary>
public class GenTass64 : IGenerator {
private const string ASM_FILE_SUFFIX = "_64tass.S"; // must start with underscore
private const int MAX_OPERAND_LEN = 64;
// IGenerator
public DisasmProject Project { get; private set; }
// IGenerator
public Formatter SourceFormatter { get; private set; }
// IGenerator
public AppSettings Settings { get; private set; }
// IGenerator
public AssemblerQuirks Quirks { get; private set; }
// IGenerator
public LabelLocalizer Localizer { get { return mLocalizer; } }
/// <summary>
/// Working directory, i.e. where we write our output file(s).
/// </summary>
private string mWorkDirectory;
/// <summary>
/// If set, long labels get their own line.
/// </summary>
private bool mLongLabelNewLine;
/// <summary>
/// Output column widths.
/// </summary>
private int[] mColumnWidths;
/// <summary>
/// Base filename. Typically the project file name without the ".dis65" extension.
/// </summary>
private string mFileNameBase;
/// <summary>
/// StringBuilder to use when composing a line. Held here to reduce allocations.
/// </summary>
private StringBuilder mLineBuilder = new StringBuilder(100);
/// <summary>
/// Label localization helper.
/// </summary>
private LabelLocalizer mLocalizer;
/// <summary>
/// Stream to send the output to.
/// </summary>
private StreamWriter mOutStream;
/// <summary>
/// If we output a ".logical", we will need a ".here" eventually.
/// </summary>
private bool mNeedHereOp;
/// <summary>
/// Holds detected version of configured assembler.
/// </summary>
private CommonUtil.Version mAsmVersion = CommonUtil.Version.NO_VERSION;
// Version we're coded against.
private static CommonUtil.Version V1_53 = new CommonUtil.Version(1, 53, 1515);
// Pseudo-op string constants.
private static PseudoOp.PseudoOpNames sDataOpNames = new PseudoOp.PseudoOpNames() {
EquDirective = "=",
OrgDirective = ".logical",
//RegWidthDirective // .as, .al, .xs, .xl
DefineData1 = ".byte",
DefineData2 = ".word",
DefineData3 = ".long",
DefineData4 = ".dword",
//DefineBigData2
//DefineBigData3
//DefineBigData4
Fill = ".fill",
//Dense // no equivalent, use .byte with comma-separated args
StrGeneric = ".text",
//StrReverse
StrNullTerm = ".null",
StrLen8 = ".ptext",
//StrLen16
//StrDci
//StrDciReverse
};
private const string HERE_PSEUDO_OP = ".here";
// IGenerator
public void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps,
out Formatter.FormatConfig formatConfig) {
pseudoOps = sDataOpNames;
formatConfig = new Formatter.FormatConfig();
SetFormatConfigValues(ref formatConfig);
}
// IGenerator
public void Configure(DisasmProject project, string workDirectory, string fileNameBase,
AssemblerVersion asmVersion, AppSettings settings) {
Debug.Assert(project != null);
Debug.Assert(!string.IsNullOrEmpty(workDirectory));
Debug.Assert(!string.IsNullOrEmpty(fileNameBase));
Project = project;
Quirks = new AssemblerQuirks();
mWorkDirectory = workDirectory;
mFileNameBase = fileNameBase;
Settings = settings;
mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
AssemblerInfo.Id.Tass64);
mColumnWidths = (int[])config.ColumnWidths.Clone();
}
/// <summary>
/// Configures the assembler-specific format items.
/// </summary>
private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
config.mForceAbsOpcodeSuffix = string.Empty;
config.mForceLongOpcodeSuffix = string.Empty;
config.mForceAbsOperandPrefix = "@w"; // word
config.mForceLongOperandPrefix = "@l"; // long
config.mEndOfLineCommentDelimiter = ";";
config.mFullLineCommentDelimiterBase = ";";
config.mBoxLineCommentDelimiter = ";";
config.mAllowHighAsciiCharConst = false;
config.mUpperOpcodes = false;
config.mUpperPseudoOpcodes = false;
config.mUpperOperandA = false;
config.mUpperOperandS = false;
config.mUpperOperandXY = false;
config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Simple;
}
// IGenerator
public List<string> GenerateSource(BackgroundWorker worker) {
List<string> pathNames = new List<string>(1);
string fileName = mFileNameBase + ASM_FILE_SUFFIX;
string pathName = Path.Combine(mWorkDirectory, fileName);
pathNames.Add(pathName);
Formatter.FormatConfig config = new Formatter.FormatConfig();
GenCommon.ConfigureFormatterFromSettings(Settings, ref config);
SetFormatConfigValues(ref config);
SourceFormatter = new Formatter(config);
string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName);
worker.ReportProgress(0, msg);
mLocalizer = new LabelLocalizer(Project);
if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) {
mLocalizer.LocalPrefix = "_";
mLocalizer.Analyze();
}
mLocalizer.MaskLeadingUnderscores();
// Use UTF-8 encoding, without a byte-order mark.
using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) {
mOutStream = sw;
if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) {
OutputLine(SourceFormatter.FullLineCommentDelimiter +
string.Format(Properties.Resources.GENERATED_FOR_VERSION,
"64tass", V1_53));
}
GenCommon.Generate(this, sw, worker);
if (mNeedHereOp) {
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP),
string.Empty, string.Empty);
}
}
mOutStream = null;
return pathNames;
}
// IGenerator
public void OutputAsmConfig() {
CpuDef cpuDef = Project.CpuDef;
string cpuStr;
if (cpuDef.Type == CpuDef.CpuType.Cpu65816) {
cpuStr = "65816";
} else if (cpuDef.Type == CpuDef.CpuType.Cpu65C02) {
cpuStr = "65c02";
} else if (cpuDef.Type == CpuDef.CpuType.Cpu6502 && cpuDef.HasUndocumented) {
cpuStr = "6502i";
} else {
// 6502 def includes undocumented ops
cpuStr = "6502";
}
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(".cpu"),
'\"' + cpuStr + '\"', string.Empty);
}
// IGenerator
public string ReplaceMnemonic(OpDef op) {
if (op.IsUndocumented) {
if (Project.CpuDef.Type == CpuDef.CpuType.Cpu65C02) {
// none of the "LDD" stuff is handled
return null;
}
if ((op.Mnemonic == OpName.ANC && op.Opcode != 0x0b) ||
(op.Mnemonic == OpName.JAM && op.Opcode != 0x02)) {
// There are multiple opcodes that match the mnemonic. Output the
// mnemonic for the first one and hex for the rest.
return null;
} else if (op.Mnemonic == OpName.NOP || op.Mnemonic == OpName.DOP ||
op.Mnemonic == OpName.TOP) {
// the various undocumented no-ops aren't handled
return null;
} else if (op.Mnemonic == OpName.SBC) {
// this is the alternate reference to SBC
return null;
} else if (op == OpDef.OpSHA_DPIndIndexY) {
// not recognized ($93)
return null;
}
}
if (op == OpDef.OpBRK_StackInt || op == OpDef.OpCOP_StackInt ||
op == OpDef.OpWDM_WDM) {
// 64tass doesn't like these to have an operand. Output as hex.
return null;
}
return string.Empty; // indicate original is fine
}
// IGenerator
public void GenerateShortSequence(int offset, int length, out string opcode,
out string operand) {
Debug.Assert(length >= 1 && length <= 4);
// Use a comma-separated list of individual hex bytes.
opcode = sDataOpNames.DefineData1;
StringBuilder sb = new StringBuilder(length * 4);
for (int i = 0; i < length; i++) {
if (i != 0) {
sb.Append(',');
}
sb.Append(SourceFormatter.FormatHexValue(Project.FileData[offset + i], 2));
}
operand = sb.ToString();
}
// IGenerator
public void OutputDataOp(int offset) {
Formatter formatter = SourceFormatter;
byte[] data = Project.FileData;
Anattrib attr = Project.GetAnattrib(offset);
string labelStr = string.Empty;
if (attr.Symbol != null) {
labelStr = mLocalizer.ConvLabel(attr.Symbol.Label);
}
string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]);
string opcodeStr, operandStr;
FormatDescriptor dfd = attr.DataDescriptor;
Debug.Assert(dfd != null);
int length = dfd.Length;
Debug.Assert(length > 0);
bool multiLine = false;
switch (dfd.FormatType) {
case FormatDescriptor.Type.Default:
if (length != 1) {
Debug.Assert(false);
length = 1;
}
opcodeStr = sDataOpNames.DefineData1;
int operand = RawData.GetWord(data, offset, length, false);
operandStr = formatter.FormatHexValue(operand, length * 2);
break;
case FormatDescriptor.Type.NumericLE:
opcodeStr = sDataOpNames.GetDefineData(length);
operand = RawData.GetWord(data, offset, length, false);
operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
mLocalizer.LabelMap, dfd, operand, length, false);
break;
case FormatDescriptor.Type.NumericBE:
opcodeStr = sDataOpNames.GetDefineBigData(length);
if (opcodeStr == null) {
// Nothing defined, output as comma-separated single-byte values.
GenerateShortSequence(offset, length, out opcodeStr, out operandStr);
} else {
operand = RawData.GetWord(data, offset, length, true);
operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable,
mLocalizer.LabelMap, dfd, operand, length, false);
}
break;
case FormatDescriptor.Type.Fill:
opcodeStr = sDataOpNames.Fill;
operandStr = length + "," + formatter.FormatHexValue(data[offset], 2);
break;
case FormatDescriptor.Type.Dense:
multiLine = true;
opcodeStr = operandStr = null;
OutputDenseHex(offset, length, labelStr, commentStr);
break;
case FormatDescriptor.Type.String:
multiLine = true;
opcodeStr = operandStr = null;
OutputString(offset, labelStr, commentStr);
break;
default:
opcodeStr = "???";
operandStr = "***";
break;
}
if (!multiLine) {
opcodeStr = formatter.FormatPseudoOp(opcodeStr);
OutputLine(labelStr, opcodeStr, operandStr, commentStr);
}
}
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
Formatter formatter = SourceFormatter;
byte[] data = Project.FileData;
StringBuilder sb = new StringBuilder(MAX_OPERAND_LEN);
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.DefineData1);
int maxPerLine = MAX_OPERAND_LEN / 4;
int numChunks = (length + maxPerLine - 1) / maxPerLine;
for (int chunk = 0; chunk < numChunks; chunk++) {
int chunkStart = chunk * maxPerLine;
int chunkEnd = Math.Min((chunk + 1) * maxPerLine, length);
for (int i = chunkStart; i < chunkEnd; i++) {
if (i != chunkStart) {
sb.Append(',');
}
sb.Append(formatter.FormatHexValue(data[offset + i], 2));
}
OutputLine(labelStr, opcodeStr, sb.ToString(), commentStr);
labelStr = commentStr = string.Empty;
sb.Clear();
}
}
/// <summary>
/// Outputs formatted data in an unformatted way, because the code generator couldn't
/// figure out how to do something better.
/// </summary>
private void OutputNoJoy(int offset, int length, string labelStr, string commentStr) {
byte[] data = Project.FileData;
Debug.Assert(length > 0);
Debug.Assert(offset >= 0 && offset < data.Length);
bool singleValue = true;
byte val = data[offset];
for (int i = 1; i < length; i++) {
if (data[offset + i] != val) {
singleValue = false;
break;
}
}
if (singleValue) {
string opcodeStr = SourceFormatter.FormatPseudoOp(sDataOpNames.Fill);
string operandStr = length + "," + SourceFormatter.FormatHexValue(val, 2);
OutputLine(labelStr, opcodeStr, operandStr, commentStr);
} else {
OutputDenseHex(offset, length, labelStr, commentStr);
}
}
// IGenerator
public void OutputEquDirective(string name, string valueStr, string comment) {
OutputLine(name, SourceFormatter.FormatPseudoOp(sDataOpNames.EquDirective),
valueStr, SourceFormatter.FormatEolComment(comment));
}
// IGenerator
public void OutputOrgDirective(int offset, int address) {
// 64tass separates the "compile offset", which determines where the output fits
// into the generated binary, and "program counter", which determines the code
// the assembler generates. Since we need to explicitly specify every byte in
// the output file, the compile offset isn't very useful. We want to set it once
// before the first line of code, then leave it alone.
//
// Any subsequent ORG changes are made to the program counter, and take the form
// of a pair of ops (.logical <addr> to open, .here to end). Omitting the .here
// causes an error.
if (offset == 0) {
// Set the "compile offset", which determines where assembled code goes in the
// output file. This
//
// This is different from the "program counter", which determines how code is
// actually assembled.
OutputLine("*", "=", SourceFormatter.FormatHexValue(Project.AddrMap.Get(0), 4),
string.Empty);
} else {
if (mNeedHereOp) {
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP),
string.Empty, string.Empty);
}
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective),
SourceFormatter.FormatHexValue(address, 4), string.Empty);
mNeedHereOp = true;
}
}
// IGenerator
public void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX) {
if (prevM != newM) {
string mop = (newM == 0) ? ".al" : ".as";
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(mop),
string.Empty, string.Empty);
}
if (prevX != newX) {
string xop = (newX == 0) ? ".xl" : ".xs";
OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(xop),
string.Empty, string.Empty);
}
}
// IGenerator
public void OutputLine(string fullLine) {
mOutStream.WriteLine(fullLine);
}
// IGenerator
public void OutputLine(string label, string opcode, string operand, string comment) {
// Break the line if the label is long and it's not a .EQ directive.
if (!string.IsNullOrEmpty(label) &&
!string.Equals(opcode, sDataOpNames.EquDirective,
StringComparison.InvariantCultureIgnoreCase)) {
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
mOutStream.WriteLine(label);
label = string.Empty;
}
}
mLineBuilder.Clear();
TextUtil.AppendPaddedString(mLineBuilder, label, mColumnWidths[0]);
TextUtil.AppendPaddedString(mLineBuilder, opcode, mColumnWidths[0] + mColumnWidths[1]);
TextUtil.AppendPaddedString(mLineBuilder, operand,
mColumnWidths[0] + mColumnWidths[1] + mColumnWidths[2]);
if (string.IsNullOrEmpty(comment)) {
// Trim trailing spaces off of opcode or operand. If they want trailing
// spaces at the end of a comment, that's fine.
CommonUtil.TextUtil.TrimEnd(mLineBuilder);
} else {
mLineBuilder.Append(comment);
}
mOutStream.WriteLine(mLineBuilder.ToString());
}
private void OutputString(int offset, string labelStr, string commentStr) {
// Normal ASCII strings are straightforward: they're just part of a .byte
// directive, and can mix with anything else in the .byte.
//
// For CString we can use .asciiz, but only if the string fits on one line
// and doesn't include delimiters. For L8String and L16String we can
// define simple macros, but their use has a similar restriction. High-ASCII
// strings also require a macro.
//
// We might be able to define a macro for DCI and Reverse as well.
//
// The limitation on strings with delimiters arises because (1) I don't see a
// way to escape them within a string, and (2) the simple macro workarounds
// only take a single argument, not a comma-separated list of stuff.
//
// Some ideas here:
// https://groups.google.com/forum/#!topic/comp.sys.apple2.programmer/5Wkw8mUPcU0
Formatter formatter = SourceFormatter;
byte[] data = Project.FileData;
Anattrib attr = Project.GetAnattrib(offset);
FormatDescriptor dfd = attr.DataDescriptor;
Debug.Assert(dfd != null);
Debug.Assert(dfd.FormatType == FormatDescriptor.Type.String);
Debug.Assert(dfd.Length > 0);
bool highAscii = false;
int leadingBytes = 0;
int trailingBytes = 0;
bool showLeading = false;
bool showTrailing = false;
switch (dfd.FormatSubType) {
case FormatDescriptor.SubType.None:
highAscii = (data[offset] & 0x80) != 0;
break;
case FormatDescriptor.SubType.Dci:
highAscii = (data[offset] & 0x80) != 0;
trailingBytes = 1;
showTrailing = true;
break;
case FormatDescriptor.SubType.Reverse:
highAscii = (data[offset] & 0x80) != 0;
break;
case FormatDescriptor.SubType.DciReverse:
highAscii = (data[offset + dfd.Length - 1] & 0x80) != 0;
leadingBytes = 1;
showLeading = true;
break;
case FormatDescriptor.SubType.CString:
highAscii = (data[offset] & 0x80) != 0;
trailingBytes = 1;
showTrailing = true;
break;
case FormatDescriptor.SubType.L8String:
if (dfd.Length > 1) {
highAscii = (data[offset + 1] & 0x80) != 0;
}
leadingBytes = 1;
showLeading = true;
break;
case FormatDescriptor.SubType.L16String:
if (dfd.Length > 2) {
highAscii = (data[offset + 2] & 0x80) != 0;
}
leadingBytes = 2;
showLeading = true;
break;
default:
Debug.Assert(false);
return;
}
char delim = '"';
StringGather gath = null;
// Run the string through so we can see if it'll fit on one line. As a minor
// optimization, we skip this step for "generic" strings, which are probably
// the most common thing.
if (dfd.FormatSubType != FormatDescriptor.SubType.None || highAscii) {
gath = new StringGather(this, labelStr, "???", commentStr, delim,
delim, StringGather.ByteStyle.CommaSep, MAX_OPERAND_LEN, true);
FeedGath(gath, data, offset, dfd.Length, leadingBytes, showLeading,
trailingBytes, showTrailing);
Debug.Assert(gath.NumLinesOutput > 0);
}
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.StrGeneric);
switch (dfd.FormatSubType) {
case FormatDescriptor.SubType.None:
// TODO: something fancy with encodings to handle high-ASCII text?
break;
case FormatDescriptor.SubType.Dci:
case FormatDescriptor.SubType.Reverse:
case FormatDescriptor.SubType.DciReverse:
// Full configured above.
break;
case FormatDescriptor.SubType.CString:
if (gath.NumLinesOutput == 1 && !gath.HasDelimiter) {
opcodeStr = sDataOpNames.StrNullTerm;
showTrailing = false;
}
break;
case FormatDescriptor.SubType.L8String:
if (gath.NumLinesOutput == 1 && !gath.HasDelimiter) {
opcodeStr = sDataOpNames.StrLen8;
showLeading = false;
}
break;
case FormatDescriptor.SubType.L16String:
// Implement as macro?
break;
default:
Debug.Assert(false);
return;
}
if (highAscii) {
OutputNoJoy(offset, dfd.Length, labelStr, commentStr);
return;
}
// Create a new StringGather, with the final opcode choice.
gath = new StringGather(this, labelStr, opcodeStr, commentStr, delim,
delim, StringGather.ByteStyle.CommaSep, MAX_OPERAND_LEN, false);
FeedGath(gath, data, offset, dfd.Length, leadingBytes, showLeading,
trailingBytes, showTrailing);
}
/// <summary>
/// Feeds the bytes into the StringGather.
/// </summary>
private void FeedGath(StringGather gath, byte[] data, int offset, int length,
int leadingBytes, bool showLeading, int trailingBytes, bool showTrailing) {
int startOffset = offset;
int strEndOffset = offset + length - trailingBytes;
if (showLeading) {
while (leadingBytes-- > 0) {
gath.WriteByte(data[offset++]);
}
} else {
offset += leadingBytes;
}
for (; offset < strEndOffset; offset++) {
gath.WriteChar((char)(data[offset] & 0x7f));
}
while (showTrailing && trailingBytes-- > 0) {
gath.WriteByte(data[offset++]);
}
gath.Finish();
}
}
#endregion IGenerator
#region IAssembler
/// <summary>
/// Cross-assembler execution interface.
/// </summary>
public class AsmTass64 : IAssembler {
// Paths from generator.
private List<string> mPathNames;
// Directory to make current before executing assembler.
private string mWorkDirectory;
// IAssembler
public void GetExeIdentifiers(out string humanName, out string exeName) {
humanName = "64tass Assembler";
exeName = "64tass";
}
// IAssembler
public AssemblerConfig GetDefaultConfig() {
return new AssemblerConfig(string.Empty, new int[] { 8, 8, 11, 73 });
}
// IAssembler
public AssemblerVersion QueryVersion() {
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Tass64);
if (config == null || string.IsNullOrEmpty(config.ExecutablePath)) {
return null;
}
ShellCommand cmd = new ShellCommand(config.ExecutablePath, "--version",
Directory.GetCurrentDirectory(), null);
cmd.Execute();
if (string.IsNullOrEmpty(cmd.Stdout)) {
return null;
}
// Windows - Stdout: "64tass Turbo Assembler Macro V1.53.1515\r\n"
// Linux - Stdout: "64tass Turbo Assembler Macro V1.53.1515?\n"
const string PREFIX = "Macro V";
string str = cmd.Stdout;
int start = str.IndexOf(PREFIX);
int end = (start < 0) ? -1 : str.IndexOfAny(new char[] { '?', '\r', '\n' }, start + 1);
if (start < 0 || end < 0 || start + PREFIX.Length >= end) {
Debug.WriteLine("Couldn't find version in " + str);
return null;
}
start += PREFIX.Length;
string versionStr = str.Substring(start, end - start);
CommonUtil.Version version = CommonUtil.Version.Parse(versionStr);
if (!version.IsValid) {
return null;
}
return new AssemblerVersion(versionStr, version);
}
// IAssembler
public void Configure(List<string> pathNames, string workDirectory) {
// Clone pathNames, in case the caller decides to modify the original.
mPathNames = new List<string>(pathNames.Count);
foreach (string str in pathNames) {
mPathNames.Add(str);
}
mWorkDirectory = workDirectory;
}
// IAssembler
public AssemblerResults RunAssembler(BackgroundWorker worker) {
// Reduce input file to a partial path if possible. This is really just to make
// what we display to the user a little easier to read.
string pathName = mPathNames[0];
if (pathName.StartsWith(mWorkDirectory)) {
pathName = pathName.Remove(0, mWorkDirectory.Length + 1);
} else {
// Unexpected, but shouldn't be a problem.
Debug.WriteLine("NOTE: source file is not in work directory");
}
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Tass64);
if (string.IsNullOrEmpty(config.ExecutablePath)) {
Debug.WriteLine("Assembler not configured");
return null;
}
string options = "--case-sensitive --nostart --long-address -Wall";
string outFileName = pathName.Substring(0, pathName.Length - 2);
// Wrap pathname in quotes in case it has spaces.
// (Do we need to shell-escape quotes in the pathName?)
ShellCommand cmd = new ShellCommand(config.ExecutablePath,
options + " \"" + pathName + "\"" + " -o \"" + outFileName + "\"",
mWorkDirectory, null);
cmd.Execute();
// Can't really do anything with a "cancel" request.
// Output filename is the input filename without the ".S". Since the filename
// was generated by us we can be confident in the format.
string outputFile = mPathNames[0].Substring(0, mPathNames[0].Length - 2);
return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout,
cmd.Stderr, outputFile);
}
}
#endregion IAssembler
}

View File

@ -30,6 +30,7 @@ namespace SourceGen.AsmGen {
/// </summary>
public enum Id {
Unknown = 0,
Tass64,
Cc65,
Merlin32,
}
@ -41,6 +42,7 @@ namespace SourceGen.AsmGen {
/// </summary>
private static AssemblerInfo[] sInfo = new AssemblerInfo[] {
new AssemblerInfo(Id.Unknown, "???", null, null),
new AssemblerInfo(Id.Tass64, "64tass", typeof(GenTass64), typeof(AsmTass64)),
new AssemblerInfo(Id.Cc65, "cc65", typeof(GenCc65), typeof(AsmCc65)),
new AssemblerInfo(Id.Merlin32, "Merlin 32", typeof(GenMerlin32), typeof(AsmMerlin32)),
};

View File

@ -226,7 +226,7 @@ namespace SourceGen.AsmGen {
private bool IsAssemblerConfigured() {
AssemblerConfig config =
AssemblerConfig.GetConfig(AppSettings.Global, mSelectedAssemblerId);
return !string.IsNullOrEmpty(config.ExecutablePath);
return config != null && !string.IsNullOrEmpty(config.ExecutablePath);
}
private void assemblerSettingsButton_Click(object sender, EventArgs e) {

View File

@ -66,7 +66,7 @@ namespace SourceGen.AsmGen {
// Check for address change.
int orgAddr = proj.AddrMap.Get(offset);
if (orgAddr >= 0) {
gen.OutputOrgDirective(orgAddr);
gen.OutputOrgDirective(offset, orgAddr);
}
if (attr.IsInstructionStart) {

View File

@ -128,8 +128,9 @@ namespace SourceGen.AsmGen {
/// <summary>
/// Outputs a code origin directive.
/// </summary>
/// <param name="offset">Offset of code targeted to new address.</param>
/// <param name="address">24-bit address.</param>
void OutputOrgDirective(int address);
void OutputOrgDirective(int offset, int address);
/// <summary>
/// Notify the assembler of a change in register width.

View File

@ -126,7 +126,7 @@ namespace SourceGen.AsmGen {
public Dictionary<string, string> LabelMap { get; private set; }
/// <summary>
/// String to prefix to local labels.
/// String to prefix to local labels. Usually a single character, like ':' or '@'.
/// </summary>
public string LocalPrefix { get; set; }
@ -309,5 +309,35 @@ namespace SourceGen.AsmGen {
}
}
}
/// <summary>
/// Adjusts the label map so that only local variables start with an underscore ('_').
/// This is necessary for assemblers like 64tass that use a leading underscore to
/// indicate that a label should be local.
///
/// This may be called even if label localization is disabled. In that case we just
/// create an empty label map and populate as needed.
/// </summary>
public void MaskLeadingUnderscores() {
bool allGlobal = false;
if (LabelMap == null) {
allGlobal = true;
LabelMap = new Dictionary<string, string>();
}
for (int i = 0; i < mProject.FileDataLength; i++) {
Symbol sym = mProject.GetAnattrib(i).Symbol;
if (sym == null) {
// No label at this offset.
continue;
}
if (sym.Label.StartsWith("_") && (allGlobal || mGlobalFlags[i])) {
Debug.WriteLine("Adjusting " + sym.Label);
// TODO: uniquify
LabelMap[sym.Label] = "X" + sym.Label;
}
}
}
}
}

View File

@ -520,7 +520,7 @@ namespace SourceGen.Properties {
}
/// <summary>
/// Looks up a localized string similar to Assembler: {0} (latest).
/// Looks up a localized string similar to Target assembler: {0} (latest).
/// </summary>
internal static string GENERATED_FOR_LATEST {
get {
@ -529,7 +529,7 @@ namespace SourceGen.Properties {
}
/// <summary>
/// Looks up a localized string similar to Assembler: {0} v{1}.
/// Looks up a localized string similar to Target assembler: {0} v{1}.
/// </summary>
internal static string GENERATED_FOR_VERSION {
get {

View File

@ -271,10 +271,10 @@
<value>Symbol value: {0}</value>
</data>
<data name="GENERATED_FOR_LATEST" xml:space="preserve">
<value>Assembler: {0} (latest)</value>
<value>Target assembler: {0} (latest)</value>
</data>
<data name="GENERATED_FOR_VERSION" xml:space="preserve">
<value>Assembler: {0} v{1}</value>
<value>Target assembler: {0} v{1}</value>
</data>
<data name="HIDE_COL" xml:space="preserve">
<value>Hide</value>

View File

@ -24,6 +24,7 @@ for each.</p>
<p>SourceGen currently supports the following cross-assemblers:</p>
<ul>
<li><a href="https://sourceforge.net/projects/tass64/">64tass</a> v1.53.1515 or later</li>
<li><a href="https://cc65.github.io/">cc65</a> v2.17 or later</li>
<li><a href="https://www.brutaldeluxe.fr/products/crossdevtools/merlin/">Merlin 32</a> v1.0.0 or later</li>
</ul>
@ -105,6 +106,104 @@ and report any differences.</p>
SourceGen. However, SourceGen can generally work around assembler bugs,
so any failure is an opportunity for improvement.</p>
<h2><a name="quirks">Assembler-Specific Bugs &amp; Quirks</a></h2>
<p>This is a list of bugs and quirky behavior in cross-assemblers that
SourceGen works around when generating code.</p>
<p>Every assembler seems to have a different way of dealing with expressions.
Most of them will let you group expressions with parenthesis, but that
doesn't always help. For example, <code>PEA label >> 8 + 1</code> is
perfectly valid, but writing <code>PEA (label >> 8) + 1</code> will cause
most assemblers to assume you're trying to use an alterate form of PEA
with indirect addressing (which doesn't exist). The code generator needs
to understand expression syntax and operator precedence to generate correct
code, but also needs to know how to handle the corner cases.</p>
<h3><a name="64tass">64tass</a></h3>
<p>Code is generated for 64tass v1.53.1515.</p>
<p>Bugs:</p>
<ul>
<li>Undocumented opcodes: <code>SHA (ZP),Y</code> ($93) is not supported;
the assembler appears to be expecting <code>SHA ABS,X</code> instead.</li>
<li>BRK, COP, and WDM are not allowed to have operands.</li>
</ul>
<p>Quirks:</p>
<ul>
<li>The underscore character ('_') is allowed as a character in labels,
but when used as the first character in a label it indicates the
label is local. If you create labels with leading underscores that
are not local, the labels must be altered to start with some other
character, and made unique.</li>
<li>By default, 64tass sets the first two bytes of the output file to
the load address. The <code>--nostart</code> flag is used to
suppress this.</li>
<li>By default, 64tass is case-insensitive, but SourceGen treats labels
as case-sensitive. The <code>--case-sensitive</code> must be passed to
the assembler.</li>
<li>If you set the <code>--case-sensitive</code> flag, <b>all</b> opcodes
and operands must be lower-case. Most of the flags used to show
things in upper case must be disabled.</li>
<li>For 65816, selecting the bank byte is done with the back-quote ('`')
rather than the caret ('^'). (There's a note in the docs to the effect
that they plan to move to carets.)</li>
</ul>
<h3><a name="cc65">cc65</a></h3>
<p>Code is generated for cc65 v2.27.</p>
<p>Bugs:</p>
<ul>
<li>The arguments to MVN/MVP are reversed.</li>
<li>PC relative branches don't wrap around at bank boundaries.</li>
<li>BRK &lt;arg&gt; is assembled to opcode $05 rather than $00.</li>
<li>WDM is not supported.</li>
</ul>
<p>Quirks:</p>
<ul>
<li>Operator precedence is unusual. Consider <code>label >> 8 - 16</code>.
cc65 puts shift higher than subtraction, whereas languages like C
and assemblers like 64tass do it the other way around. So cc65
regards the expression as <code>(label >> 8) - 16</code>, while the
more common interpretation would be <code>label >> (8 - 16)</code>.
(This is actually somewhat convenient, since many common expressions
don't require parenthesis.)</li>
<li>Undocumented opcodes: SBX ($cb) uses the mnemonic AXS. All other
opcodes match up with the "unintended opcodes" document.</li>
</ul>
<h3><a name="merlin32">Merlin 32</a></h3>
<p>Code is generated for Merlin 32 v1.0.</p>
<p>Bugs:</p>
<ul>
<li>PC relative branches don't wrap around at bank boundaries.</li>
<li>For some failures, an exit code of zero is returned.</li>
</ul>
<p>Quirks:</p>
<ul>
<li>Operator precedence is unusual. Expressions are processed from
left to right, with no operator precedence.</li>
<li>The byte selection operators ('&lt;', '&gt;', '^') are actually
word-selection operators, yielding 16-bit values when wide registers
are enabled on the 65816.</p>
<li>The assembler tracks register widths when it sees SEP/REP instructions,
but doesn't attempt to track the emulation flag. So if the registers
are long when you switch to emulation, incorrect code is generated.
(Really I just want to be able to turn the auto-tracking off.)</li>
<li>Non-unique local labels don't cause an error.</li>
</ul>
</div>
<div id="footer">

View File

@ -85,6 +85,12 @@ and 65816 code. The official web site is
<li><a href="codegen.html#localizer">Label Localizer</a></li>
</ul></li>
<li><a href="codegen.html#assemble">Cross-Assembling Generated Code</a></li>
<li><a href="codegen.html#quirks">Assembler-Specific Bugs &amp; Quirks</a>
<ul>
<li><a href="codegen.html#64tass">64tass</a></li>
<li><a href="codegen.html#cc65">cc65</a></li>
<li><a href="codegen.html#merlin32">Merlin 32</a></li>
</ul></li>
</ul></li>
<li><a href="settings.html">Properties &amp; Settings</a>

View File

@ -0,0 +1,285 @@
.cpu "65816"
* = $1000
.as
.xs
sec
xce
jsr L101F
jsr L10AB
jsr L10F2
jsr L1106
jsr L1109
jsr L112C
jsr L11F9
jsr L11FC
nop
nop
nop
.byte $00,$ff
L101F ora ($ff,x)
.byte $02,$ff
ora $ff,s
tsb $ff
ora $ff
asl $ff
ora [$ff]
php
ora #$ff
asl a
phd
tsb $feff
ora $feff
asl $feff
ora $fdfeff
bpl L1041
L1041 ora ($ff),y
ora ($ff)
ora ($ff,s),y
trb $ff
ora $ff,x
asl $ff,x
ora [$ff],y
clc
ora $feff,y
inc a
tcs
trb $feff
ora $feff,x
asl $feff,x
ora $fdfeff,x
jsr $feff
and ($ff,x)
jsl $fdfeff
and $ff,s
bit $ff
and $ff
rol $ff
and [$ff]
plp
and #$ff
rol a
pld
bit $feff
and $feff
rol $feff
and $fdfeff
bmi L1089
L1089 and ($ff),y
and ($ff)
and ($ff,s),y
bit $ff,x
and $ff,x
rol $ff,x
and [$ff],y
sec
and $feff,y
dec a
tsc
bit $feff,x
and $feff,x
rol $feff,x
and $fdfeff,x
rti
L10AB eor ($ff,x)
.byte $42,$ff
eor $ff,s
mvp $fe,$ff
eor $ff
lsr $ff
eor [$ff]
pha
eor #$ff
lsr a
phk
jmp L10C2
L10C2 eor $feff
lsr $feff
eor $fdfeff
bvc L10CE
L10CE eor ($ff),y
eor ($ff)
eor ($ff,s),y
mvn $fe,$ff
eor $ff,x
lsr $ff,x
eor [$ff],y
cli
eor $feff,y
phy
tcd
jml L10E7
L10E7 eor $feff,x
lsr $feff,x
eor $fdfeff,x
rts
L10F2 adc ($ff,x)
per $0ff6
adc $ff,s
stz $ff
adc $ff
ror $ff
adc [$ff]
pla
adc #$ff
ror a
rtl
L1106 jmp ($feff)
L1109 adc $feff
ror $feff
adc $fdfeff
bvs L1115
L1115 adc ($ff),y
adc ($ff)
adc ($ff,s),y
stz $ff,x
adc $ff,x
ror $ff,x
adc [$ff],y
sei
adc $feff,y
ply
tdc
jmp ($feff,x)
L112C adc $feff,x
ror $feff,x
adc $fdfeff,x
bra L1138
L1138 sta ($ff,x)
brl L113D
L113D sta $ff,s
sty $ff
sta $ff
stx $ff
sta [$ff]
dey
bit #$ff
txa
phb
sty $feff
sta $feff
stx $feff
sta $fdfeff
bcc L115B
L115B sta ($ff),y
sta ($ff)
sta ($ff,s),y
sty $ff,x
sta $ff,x
stx $ff,y
sta [$ff],y
tya
sta $feff,y
txs
txy
stz $feff
sta $feff,x
stz $feff,x
sta $fdfeff,x
ldy #$ff
lda ($ff,x)
ldx #$ff
lda $ff,s
ldy $ff
lda $ff
ldx $ff
lda [$ff]
tay
lda #$ff
tax
plb
ldy $feff
lda $feff
ldx $feff
lda $fdfeff
bcs L11A0
L11A0 lda ($ff),y
lda ($ff)
lda ($ff,s),y
ldy $ff,x
lda $ff,x
ldx $ff,y
lda [$ff],y
clv
lda $feff,y
tsx
tyx
ldy $feff,x
lda $feff,x
ldx $feff,y
lda $fdfeff,x
cpy #$ff
cmp ($ff,x)
rep #$00
cmp $ff,s
cpy $ff
cmp $ff
dec $ff
cmp [$ff]
iny
cmp #$ff
dex
wai
cpy $feff
cmp $feff
dec $feff
cmp $fdfeff
bne L11E5
L11E5 cmp ($ff),y
cmp ($ff)
cmp ($ff,s),y
pei ($ff)
cmp $ff,x
dec $ff,x
cmp [$ff],y
cld
cmp $feff,y
phx
stp
L11F9 jml [$feff]
L11FC cmp $feff,x
dec $feff,x
cmp $fdfeff,x
cpx #$ff
sbc ($ff,x)
sep #$00
sbc $ff,s
cpx $ff
sbc $ff
inc $ff
sbc [$ff]
inx
sbc #$ff
nop
xba
cpx $feff
sbc $feff
inc $feff
sbc $fdfeff
beq L122A
L122A sbc ($ff),y
sbc ($ff)
sbc ($ff,s),y
pea $feff
sbc $ff,x
inc $ff,x
sbc [$ff],y
sed
sbc $feff,y
plx
xce
jsr ($feff,x)
sbc $feff,x
inc $feff,x
sbc $fdfeff,x

View File

@ -0,0 +1,285 @@
.cpu "65816"
* = $1000
.as
.xs
sec
xce
jsr L101F
jsr L10AB
jsr L10F2
jsr L1106
jsr L1109
jsr L112C
jsr L11F9
jsr L11FC
nop
nop
nop
.byte $00,$00
L101F ora ($00,x)
.byte $02,$00
ora $00,s
tsb $00
ora $00
asl $00
ora [$00]
php
ora #$00
asl a
phd
tsb @w$0000
ora @w$0000
asl @w$0000
ora @l$000000
bpl L1041
L1041 ora ($00),y
ora ($00)
ora ($00,s),y
trb $00
ora $00,x
asl $00,x
ora [$00],y
clc
ora $0000,y
inc a
tcs
trb @w$0000
ora @w$0000,x
asl @w$0000,x
ora @l$000000,x
jsr $0000
and ($00,x)
jsl $000000
and $00,s
bit $00
and $00
rol $00
and [$00]
plp
and #$00
rol a
pld
bit @w$0000
and @w$0000
rol @w$0000
and @l$000000
bmi L1089
L1089 and ($00),y
and ($00)
and ($00,s),y
bit $00,x
and $00,x
rol $00,x
and [$00],y
sec
and $0000,y
dec a
tsc
bit @w$0000,x
and @w$0000,x
rol @w$0000,x
and @l$000000,x
rti
L10AB eor ($00,x)
.byte $42,$00
eor $00,s
mvp $00,$00
eor $00
lsr $00
eor [$00]
pha
eor #$00
lsr a
phk
jmp L10C2
L10C2 eor @w$0000
lsr @w$0000
eor @l$000000
bvc L10CE
L10CE eor ($00),y
eor ($00)
eor ($00,s),y
mvn $00,$00
eor $00,x
lsr $00,x
eor [$00],y
cli
eor $0000,y
phy
tcd
jml L10E7
L10E7 eor @w$0000,x
lsr @w$0000,x
eor @l$000000,x
rts
L10F2 adc ($00,x)
per $0ff6
adc $00,s
stz $00
adc $00
ror $00
adc [$00]
pla
adc #$00
ror a
rtl
L1106 jmp ($0000)
L1109 adc @w$0000
ror @w$0000
adc @l$000000
bvs L1115
L1115 adc ($00),y
adc ($00)
adc ($00,s),y
stz $00,x
adc $00,x
ror $00,x
adc [$00],y
sei
adc $0000,y
ply
tdc
jmp ($0000,x)
L112C adc @w$0000,x
ror @w$0000,x
adc @l$000000,x
bra L1138
L1138 sta ($00,x)
brl L113D
L113D sta $00,s
sty $00
sta $00
stx $00
sta [$00]
dey
bit #$00
txa
phb
sty @w$0000
sta @w$0000
stx @w$0000
sta @l$000000
bcc L115B
L115B sta ($00),y
sta ($00)
sta ($00,s),y
sty $00,x
sta $00,x
stx $00,y
sta [$00],y
tya
sta $0000,y
txs
txy
stz @w$0000
sta @w$0000,x
stz @w$0000,x
sta @l$000000,x
ldy #$00
lda ($00,x)
ldx #$00
lda $00,s
ldy $00
lda $00
ldx $00
lda [$00]
tay
lda #$00
tax
plb
ldy @w$0000
lda @w$0000
ldx @w$0000
lda @l$000000
bcs L11A0
L11A0 lda ($00),y
lda ($00)
lda ($00,s),y
ldy $00,x
lda $00,x
ldx $00,y
lda [$00],y
clv
lda $0000,y
tsx
tyx
ldy @w$0000,x
lda @w$0000,x
ldx @w$0000,y
lda @l$000000,x
cpy #$00
cmp ($00,x)
rep #$00
cmp $00,s
cpy $00
cmp $00
dec $00
cmp [$00]
iny
cmp #$00
dex
wai
cpy @w$0000
cmp @w$0000
dec @w$0000
cmp @l$000000
bne L11E5
L11E5 cmp ($00),y
cmp ($00)
cmp ($00,s),y
pei ($00)
cmp $00,x
dec $00,x
cmp [$00],y
cld
cmp $0000,y
phx
stp
L11F9 jml [$0000]
L11FC cmp @w$0000,x
dec @w$0000,x
cmp @l$000000,x
cpx #$00
sbc ($00,x)
sep #$00
sbc $00,s
cpx $00
sbc $00
inc $00
sbc [$00]
inx
sbc #$00
nop
xba
cpx @w$0000
sbc @w$0000
inc @w$0000
sbc @l$000000
beq L122A
L122A sbc ($00),y
sbc ($00)
sbc ($00,s),y
pea $0000
sbc $00,x
inc $00,x
sbc [$00],y
sed
sbc $0000,y
plx
xce
jsr ($0000,x)
sbc @w$0000,x
inc @w$0000,x
sbc @l$000000,x

View File

@ -0,0 +1,77 @@
.cpu "65816"
* = $1000
.as
.xs
clc
xce
sep #$30
jsr L1014
jsr L101C
jsr L102A
jsr L102F
jsr L1059
rts
L1014 lda #$00
.byte $2c
L1017 lda #$01
beq L1017
rts
L101C sep #$30
lda $00
beq L1025
lda #$00
.byte $00
L1025 sta $012345
rts
L102A .byte $20
L102B rts
.byte $ea
bra L102B
L102F .byte $2c
L1030 .byte $2c
L1031 .byte $2c
L1032 .byte $2c
L1033 .byte $2c
L1034 .byte $2c
L1035 .byte $2c
L1036 .byte $2c
L1037 .byte $2c
L1038 nop
nop
asl a
bcc L102F
asl a
bcc L1030
asl a
bcc L1031
asl a
bcc L1032
asl a
bcc L1033
asl a
bcc L1034
asl a
bcc L1035
asl a
bcc L1036
asl a
bcc L1037
asl a
bcc L1038
rts
L1059 .byte $2c
L105A nop
.byte $ad
L105C lda $00
asl a
bcc L105A
asl a
bcc L105C
.byte $af

View File

@ -0,0 +1,260 @@
.cpu "65816"
* = $1000
.as
.xs
clc
xce
sep #$ff
clv
cld
cli
clc
lda #$80
lda #$01
sed
sei
sec
lda #$ff
adc #$00
sep #$ff
rep #$80
rep #$40
rep #$20
.al
rep #$10
.xl
rep #$08
rep #$04
rep #$02
rep #$01
sep #$00
sep #$ff
.as
.xs
rep #$00
rep #$ff
.al
.xl
lda #$feed
sec
xce
.as
.xs
lda #$ff
rep #$30
lda #$ff
clc
xce
lda #$ff
rep #$20
.al
sep #$10
lda #$0000
ldx #$01
ldy #$02
sep #$20
.as
rep #$10
.xl
lda #$01
ldx #$0000
ldy #$0000
sep #$30
.xs
lda #$00
pha
plp
rep #$80
bpl L105F
.byte $00
.byte $00
L105F sep #$80
bpl L1065
bmi L1067
L1065 .byte $00
.byte $00
L1067 rep #$40
bvc L106D
.byte $00
.byte $00
L106D sep #$40
bvs L1073
.byte $00
.byte $00
L1073 rep #$01
bcc L1079
.byte $00
.byte $00
L1079 sep #$01
bcs L107F
.byte $00
.byte $00
L107F rep #$02
bne L1085
.byte $00
.byte $00
L1085 sep #$02
beq L108B
.byte $00
.byte $00
L108B sep #$ff
lda #$01
bne L1093
.byte $00
.byte $db
L1093 lda #$00
beq L1099
.byte $00
.byte $db
L1099 bpl L109D
.byte $00
.byte $db
L109D lda #$80
bmi L10A3
.byte $00
.byte $db
L10A3 lda #$ff
and #$00
beq L10AB
.byte $00
.byte $db
L10AB lda #$00
and #$ff
beq L10B3
.byte $00
.byte $db
L10B3 lda #$ff
and #$7f
bne L10BB
.byte $00
.byte $db
L10BB bpl L10BF
.byte $00
.byte $db
L10BF lda #$ff
and #$80
bmi L10C7
.byte $00
.byte $db
L10C7 lda #$00
ora #$00
beq L10CF
.byte $00
.byte $db
L10CF ora #$01
bne L10D5
.byte $00
.byte $db
L10D5 lda #$00
ora #$7f
bpl L10DD
.byte $00
.byte $db
L10DD ora #$80
bmi L10E3
.byte $00
.byte $db
L10E3 lda L10E3
sec
ror a
bmi L10EC
.byte $00
.byte $dc
L10EC clc
ror a
bpl L10F2
.byte $00
.byte $dc
L10F2 lda #$00
sec
rol a
bne L10FA
.byte $00
.byte $dc
L10FA clc
php
sec
plp
bcc L1102
.byte $00
.byte $00
L1102 rep #$20
.al
sep #$10
jsr L111D
rep #$30
.xl
jsr L1123
sep #$30
.as
.xs
jsr L1123
rep #$20
.al
sep #$10
jsr L111D
sep #$30
.as
rts
.al
L111D lda #$1234
ldx #$ff
rts
.as
L1123 lda #$ff
ldx #$ee
ldy #$dd
rts

View File

@ -0,0 +1,35 @@
.cpu "65816"
* = $1000
.as
.xs
lda L10AC
ora L10BC
rts
.byte $33
.byte $33
.byte $33
.byte $80
.text "4444"
.byte $80
.text "55555"
.byte $80
.text "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"
.byte $80
.fill 63,$4c
.byte $81
.byte $00
.byte $00
.byte $00
.byte $81
.byte $00
.byte $00
.byte $00
.byte $00
.byte $81
.fill 5,$00
.byte $81
.fill 8,$00
L10AC .fill 8,$00
.fill 8,$82
L10BC .fill 8,$82

View File

@ -0,0 +1,294 @@
.cpu "6502i"
* = $1000
jsr L1035
jsr L1038
jsr L1059
jsr L107D
jsr L109E
jsr L10BD
jsr L10C0
jsr L10E1
jsr L1100
jsr L1103
jsr L1116
jsr L1124
jsr L1169
jsr L11AE
jsr L11F3
jsr L1238
nop
nop
nop
.byte $00,$ff
L1035 ora ($ff,x)
jam
L1038 slo ($ff,x)
.byte $04,$ff
ora $ff
asl $ff
slo $ff
php
ora #$ff
asl a
anc #$ff
.byte $0c,$ff,$fe
ora $feff
asl $feff
slo $feff
bpl L1056
L1056 ora ($ff),y
.byte $12
L1059 slo ($ff),y
.byte $14,$ff
ora $ff,x
asl $ff,x
slo $ff,x
clc
ora $feff,y
.byte $1a
slo $feff,y
.byte $1c,$ff,$fe
ora $feff,x
asl $feff,x
slo $feff,x
jsr $feff
and ($ff,x)
.byte $22
L107D rla ($ff,x)
bit $ff
and $ff
rol $ff
rla $ff
plp
and #$ff
rol a
.byte $2b,$ff
bit $feff
and $feff
rol $feff
rla $feff
bmi L109B
L109B and ($ff),y
.byte $32
L109E rla ($ff),y
.byte $34,$ff
and $ff,x
rol $ff,x
rla $ff,x
sec
and $feff,y
.byte $3a
rla $feff,y
.byte $3c,$ff,$fe
and $feff,x
rol $feff,x
rla $feff,x
rti
L10BD eor ($ff,x)
.byte $42
L10C0 sre ($ff,x)
.byte $44,$ff
eor $ff
lsr $ff
sre $ff
pha
eor #$ff
lsr a
alr #$ff
jmp L10D3
L10D3 eor $feff
lsr $feff
sre $feff
bvc L10DE
L10DE eor ($ff),y
.byte $52
L10E1 sre ($ff),y
.byte $54,$ff
eor $ff,x
lsr $ff,x
sre $ff,x
cli
eor $feff,y
.byte $5a
sre $feff,y
.byte $5c,$ff,$fe
eor $feff,x
lsr $feff,x
sre $feff,x
rts
L1100 adc ($ff,x)
.byte $62
L1103 rra ($ff,x)
.byte $64,$ff
adc $ff
ror $ff
rra $ff
pla
adc #$ff
ror a
arr #$ff
jmp ($feff)
L1116 adc $feff
ror $feff
rra $feff
bvs L1121
L1121 adc ($ff),y
.byte $72
L1124 rra ($ff),y
.byte $74,$ff
adc $ff,x
ror $ff,x
rra $ff,x
sei
adc $feff,y
.byte $7a
rra $feff,y
.byte $7c,$ff,$fe
adc $feff,x
ror $feff,x
rra $feff,x
.byte $80,$ff
sta ($ff,x)
.byte $82,$ff
sax ($ff,x)
sty $ff
sta $ff
stx $ff
sax $ff
dey
.byte $89,$ff
txa
ane #$ff
sty $feff
sta $feff
stx $feff
sax $feff
bcc L1166
L1166 sta ($ff),y
.byte $92
L1169 .byte $93,$ff
sty $ff,x
sta $ff,x
stx $ff,y
sax $ff,y
tya
sta $feff,y
txs
tas $feff,y
shy $feff,x
sta $feff,x
shx $feff,y
sha $feff,y
ldy #$ff
lda ($ff,x)
ldx #$ff
lax ($ff,x)
ldy $ff
lda $ff
ldx $ff
lax $ff
tay
lda #$ff
tax
lax #$ff
ldy $feff
lda $feff
ldx $feff
lax $feff
bcs L11AB
L11AB lda ($ff),y
.byte $b2
L11AE lax ($ff),y
ldy $ff,x
lda $ff,x
ldx $ff,y
lax $ff,y
clv
lda $feff,y
tsx
las $feff,y
ldy $feff,x
lda $feff,x
ldx $feff,y
lax $feff,y
cpy #$ff
cmp ($ff,x)
.byte $c2,$ff
dcp ($ff,x)
cpy $ff
cmp $ff
dec $ff
dcp $ff
iny
cmp #$ff
dex
sbx #$ff
cpy $feff
cmp $feff
dec $feff
dcp $feff
bne L11F0
L11F0 cmp ($ff),y
.byte $d2
L11F3 dcp ($ff),y
.byte $d4,$ff
cmp $ff,x
dec $ff,x
dcp $ff,x
cld
cmp $feff,y
.byte $da
dcp $feff,y
.byte $dc,$ff,$fe
cmp $feff,x
dec $feff,x
dcp $feff,x
cpx #$ff
sbc ($ff,x)
.byte $e2,$ff
isc ($ff,x)
cpx $ff
sbc $ff
inc $ff
isc $ff
inx
sbc #$ff
nop
.byte $eb,$ff
cpx $feff
sbc $feff
inc $feff
isc $feff
beq L1235
L1235 sbc ($ff),y
.byte $f2
L1238 isc ($ff),y
.byte $f4,$ff
sbc $ff,x
inc $ff,x
isc $ff,x
sed
sbc $feff,y
.byte $fa
isc $feff,y
.byte $fc,$ff,$fe
sbc $feff,x
inc $feff,x
isc $feff,x

View File

@ -0,0 +1,294 @@
.cpu "6502i"
* = $1000
jsr L1035
jsr L1038
jsr L1059
jsr L107D
jsr L109E
jsr L10BD
jsr L10C0
jsr L10E1
jsr L1100
jsr L1103
jsr L1116
jsr L1124
jsr L1169
jsr L11AE
jsr L11F3
jsr L1238
nop
nop
nop
.byte $00,$00
L1035 ora ($00,x)
jam
L1038 slo ($00,x)
.byte $04,$00
ora $00
asl $00
slo $00
php
ora #$00
asl a
anc #$00
.byte $0c,$00,$00
ora @w$0000
asl @w$0000
slo @w$0000
bpl L1056
L1056 ora ($00),y
.byte $12
L1059 slo ($00),y
.byte $14,$00
ora $00,x
asl $00,x
slo $00,x
clc
ora $0000,y
.byte $1a
slo $0000,y
.byte $1c,$00,$00
ora @w$0000,x
asl @w$0000,x
slo @w$0000,x
jsr $0000
and ($00,x)
.byte $22
L107D rla ($00,x)
bit $00
and $00
rol $00
rla $00
plp
and #$00
rol a
.byte $2b,$00
bit @w$0000
and @w$0000
rol @w$0000
rla @w$0000
bmi L109B
L109B and ($00),y
.byte $32
L109E rla ($00),y
.byte $34,$00
and $00,x
rol $00,x
rla $00,x
sec
and $0000,y
.byte $3a
rla $0000,y
.byte $3c,$00,$00
and @w$0000,x
rol @w$0000,x
rla @w$0000,x
rti
L10BD eor ($00,x)
.byte $42
L10C0 sre ($00,x)
.byte $44,$00
eor $00
lsr $00
sre $00
pha
eor #$00
lsr a
alr #$00
jmp L10D3
L10D3 eor @w$0000
lsr @w$0000
sre @w$0000
bvc L10DE
L10DE eor ($00),y
.byte $52
L10E1 sre ($00),y
.byte $54,$00
eor $00,x
lsr $00,x
sre $00,x
cli
eor $0000,y
.byte $5a
sre $0000,y
.byte $5c,$00,$00
eor @w$0000,x
lsr @w$0000,x
sre @w$0000,x
rts
L1100 adc ($00,x)
.byte $62
L1103 rra ($00,x)
.byte $64,$00
adc $00
ror $00
rra $00
pla
adc #$00
ror a
arr #$00
jmp ($0000)
L1116 adc @w$0000
ror @w$0000
rra @w$0000
bvs L1121
L1121 adc ($00),y
.byte $72
L1124 rra ($00),y
.byte $74,$00
adc $00,x
ror $00,x
rra $00,x
sei
adc $0000,y
.byte $7a
rra $0000,y
.byte $7c,$00,$00
adc @w$0000,x
ror @w$0000,x
rra @w$0000,x
.byte $80,$00
sta ($00,x)
.byte $82,$00
sax ($00,x)
sty $00
sta $00
stx $00
sax $00
dey
.byte $89,$00
txa
ane #$00
sty @w$0000
sta @w$0000
stx @w$0000
sax @w$0000
bcc L1166
L1166 sta ($00),y
.byte $92
L1169 .byte $93,$00
sty $00,x
sta $00,x
stx $00,y
sax $00,y
tya
sta $0000,y
txs
tas $0000,y
shy @w$0000,x
sta @w$0000,x
shx $0000,y
sha $0000,y
ldy #$00
lda ($00,x)
ldx #$00
lax ($00,x)
ldy $00
lda $00
ldx $00
lax $00
tay
lda #$00
tax
lax #$00
ldy @w$0000
lda @w$0000
ldx @w$0000
lax @w$0000
bcs L11AB
L11AB lda ($00),y
.byte $b2
L11AE lax ($00),y
ldy $00,x
lda $00,x
ldx $00,y
lax $00,y
clv
lda $0000,y
tsx
las $0000,y
ldy @w$0000,x
lda @w$0000,x
ldx @w$0000,y
lax @w$0000,y
cpy #$00
cmp ($00,x)
.byte $c2,$00
dcp ($00,x)
cpy $00
cmp $00
dec $00
dcp $00
iny
cmp #$00
dex
sbx #$00
cpy @w$0000
cmp @w$0000
dec @w$0000
dcp @w$0000
bne L11F0
L11F0 cmp ($00),y
.byte $d2
L11F3 dcp ($00),y
.byte $d4,$00
cmp $00,x
dec $00,x
dcp $00,x
cld
cmp $0000,y
.byte $da
dcp $0000,y
.byte $dc,$00,$00
cmp @w$0000,x
dec @w$0000,x
dcp @w$0000,x
cpx #$00
sbc ($00,x)
.byte $e2,$00
isc ($00,x)
cpx $00
sbc $00
inc $00
isc $00
inx
sbc #$00
nop
.byte $eb,$00
cpx @w$0000
sbc @w$0000
inc @w$0000
isc @w$0000
beq L1235
L1235 sbc ($00),y
.byte $f2
L1238 isc ($00),y
.byte $f4,$00
sbc $00,x
inc $00,x
isc $00,x
sed
sbc $0000,y
.byte $fa
isc $0000,y
.byte $fc,$00,$00
sbc @w$0000,x
inc @w$0000,x
isc @w$0000,x

View File

@ -0,0 +1,273 @@
.cpu "65c02"
* = $1000
jsr L1014
jsr L108A
jsr L10C4
jsr L10D8
jsr L10F6
nop
nop
nop
.byte $00,$ff
L1014 ora ($ff,x)
.byte $02,$ff
.byte $03
tsb $ff
ora $ff
asl $ff
.byte $07
php
ora #$ff
asl a
.byte $0b
tsb $feff
ora $feff
asl $feff
.byte $0f
bpl L1031
L1031 ora ($ff),y
ora ($ff)
.byte $13
trb $ff
ora $ff,x
asl $ff,x
.byte $17
clc
ora $feff,y
inc a
.byte $1b
trb $feff
ora $feff,x
asl $feff,x
.byte $1f
jsr $feff
and ($ff,x)
.byte $22,$ff
.byte $23
bit $ff
and $ff
rol $ff
.byte $27
plp
and #$ff
rol a
.byte $2b
bit $feff
and $feff
rol $feff
.byte $2f
bmi L106D
L106D and ($ff),y
and ($ff)
.byte $33
bit $ff,x
and $ff,x
rol $ff,x
.byte $37
sec
and $feff,y
dec a
.byte $3b
bit $feff,x
and $feff,x
rol $feff,x
.byte $3f
rti
L108A eor ($ff,x)
.byte $42,$ff
.byte $43
.byte $44,$ff
eor $ff
lsr $ff
.byte $47
pha
eor #$ff
lsr a
.byte $4b
jmp L109E
L109E eor $feff
lsr $feff
.byte $4f
bvc L10A7
L10A7 eor ($ff),y
eor ($ff)
.byte $53
.byte $54,$ff
eor $ff,x
lsr $ff,x
.byte $57
cli
eor $feff,y
phy
.byte $5b
.byte $5c,$ff,$fe
eor $feff,x
lsr $feff,x
.byte $5f
rts
L10C4 adc ($ff,x)
.byte $62,$ff
.byte $63
stz $ff
adc $ff
ror $ff
.byte $67
pla
adc #$ff
ror a
.byte $6b
jmp ($feff)
L10D8 adc $feff
ror $feff
.byte $6f
bvs L10E1
L10E1 adc ($ff),y
adc ($ff)
.byte $73
stz $ff,x
adc $ff,x
ror $ff,x
.byte $77
sei
adc $feff,y
ply
.byte $7b
jmp ($feff,x)
L10F6 adc $feff,x
ror $feff,x
.byte $7f
bra L10FF
L10FF sta ($ff,x)
.byte $82,$ff
.byte $83
sty $ff
sta $ff
stx $ff
.byte $87
dey
bit #$ff
txa
.byte $8b
sty $feff
sta $feff
stx $feff
.byte $8f
bcc L111C
L111C sta ($ff),y
sta ($ff)
.byte $93
sty $ff,x
sta $ff,x
stx $ff,y
.byte $97
tya
sta $feff,y
txs
.byte $9b
stz $feff
sta $feff,x
stz $feff,x
.byte $9f
ldy #$ff
lda ($ff,x)
ldx #$ff
.byte $a3
ldy $ff
lda $ff
ldx $ff
.byte $a7
tay
lda #$ff
tax
.byte $ab
ldy $feff
lda $feff
ldx $feff
.byte $af
bcs L1157
L1157 lda ($ff),y
lda ($ff)
.byte $b3
ldy $ff,x
lda $ff,x
ldx $ff,y
.byte $b7
clv
lda $feff,y
tsx
.byte $bb
ldy $feff,x
lda $feff,x
ldx $feff,y
.byte $bf
cpy #$ff
cmp ($ff,x)
.byte $c2,$ff
.byte $c3
cpy $ff
cmp $ff
dec $ff
.byte $c7
iny
cmp #$ff
dex
.byte $cb
cpy $feff
cmp $feff
dec $feff
.byte $cf
bne L1192
L1192 cmp ($ff),y
cmp ($ff)
.byte $d3
.byte $d4,$ff
cmp $ff,x
dec $ff,x
.byte $d7
cld
cmp $feff,y
phx
.byte $db
.byte $dc,$ff,$fe
cmp $feff,x
dec $feff,x
.byte $df
cpx #$ff
sbc ($ff,x)
.byte $e2,$ff
.byte $e3
cpx $ff
sbc $ff
inc $ff
.byte $e7
inx
sbc #$ff
nop
.byte $eb
cpx $feff
sbc $feff
inc $feff
.byte $ef
beq L11CD
L11CD sbc ($ff),y
sbc ($ff)
.byte $f3
.byte $f4,$ff
sbc $ff,x
inc $ff,x
.byte $f7
sed
sbc $feff,y
plx
.byte $fb
.byte $fc,$ff,$fe
sbc $feff,x
inc $feff,x
.byte $ff

View File

@ -0,0 +1,273 @@
.cpu "65c02"
* = $1000
jsr L1014
jsr L108A
jsr L10C4
jsr L10D8
jsr L10F6
nop
nop
nop
.byte $00,$00
L1014 ora ($00,x)
.byte $02,$00
.byte $03
tsb $00
ora $00
asl $00
.byte $07
php
ora #$00
asl a
.byte $0b
tsb @w$0000
ora @w$0000
asl @w$0000
.byte $0f
bpl L1031
L1031 ora ($00),y
ora ($00)
.byte $13
trb $00
ora $00,x
asl $00,x
.byte $17
clc
ora $0000,y
inc a
.byte $1b
trb @w$0000
ora @w$0000,x
asl @w$0000,x
.byte $1f
jsr $0000
and ($00,x)
.byte $22,$00
.byte $23
bit $00
and $00
rol $00
.byte $27
plp
and #$00
rol a
.byte $2b
bit @w$0000
and @w$0000
rol @w$0000
.byte $2f
bmi L106D
L106D and ($00),y
and ($00)
.byte $33
bit $00,x
and $00,x
rol $00,x
.byte $37
sec
and $0000,y
dec a
.byte $3b
bit @w$0000,x
and @w$0000,x
rol @w$0000,x
.byte $3f
rti
L108A eor ($00,x)
.byte $42,$00
.byte $43
.byte $44,$00
eor $00
lsr $00
.byte $47
pha
eor #$00
lsr a
.byte $4b
jmp L109E
L109E eor @w$0000
lsr @w$0000
.byte $4f
bvc L10A7
L10A7 eor ($00),y
eor ($00)
.byte $53
.byte $54,$00
eor $00,x
lsr $00,x
.byte $57
cli
eor $0000,y
phy
.byte $5b
.byte $5c,$00,$00
eor @w$0000,x
lsr @w$0000,x
.byte $5f
rts
L10C4 adc ($00,x)
.byte $62,$00
.byte $63
stz $00
adc $00
ror $00
.byte $67
pla
adc #$00
ror a
.byte $6b
jmp ($0000)
L10D8 adc @w$0000
ror @w$0000
.byte $6f
bvs L10E1
L10E1 adc ($00),y
adc ($00)
.byte $73
stz $00,x
adc $00,x
ror $00,x
.byte $77
sei
adc $0000,y
ply
.byte $7b
jmp ($0000,x)
L10F6 adc @w$0000,x
ror @w$0000,x
.byte $7f
bra L10FF
L10FF sta ($00,x)
.byte $82,$00
.byte $83
sty $00
sta $00
stx $00
.byte $87
dey
bit #$00
txa
.byte $8b
sty @w$0000
sta @w$0000
stx @w$0000
.byte $8f
bcc L111C
L111C sta ($00),y
sta ($00)
.byte $93
sty $00,x
sta $00,x
stx $00,y
.byte $97
tya
sta $0000,y
txs
.byte $9b
stz @w$0000
sta @w$0000,x
stz @w$0000,x
.byte $9f
ldy #$00
lda ($00,x)
ldx #$00
.byte $a3
ldy $00
lda $00
ldx $00
.byte $a7
tay
lda #$00
tax
.byte $ab
ldy @w$0000
lda @w$0000
ldx @w$0000
.byte $af
bcs L1157
L1157 lda ($00),y
lda ($00)
.byte $b3
ldy $00,x
lda $00,x
ldx $00,y
.byte $b7
clv
lda $0000,y
tsx
.byte $bb
ldy @w$0000,x
lda @w$0000,x
ldx @w$0000,y
.byte $bf
cpy #$00
cmp ($00,x)
.byte $c2,$00
.byte $c3
cpy $00
cmp $00
dec $00
.byte $c7
iny
cmp #$00
dex
.byte $cb
cpy @w$0000
cmp @w$0000
dec @w$0000
.byte $cf
bne L1192
L1192 cmp ($00),y
cmp ($00)
.byte $d3
.byte $d4,$00
cmp $00,x
dec $00,x
.byte $d7
cld
cmp $0000,y
phx
.byte $db
.byte $dc,$00,$00
cmp @w$0000,x
dec @w$0000,x
.byte $df
cpx #$00
sbc ($00,x)
.byte $e2,$00
.byte $e3
cpx $00
sbc $00
inc $00
.byte $e7
inx
sbc #$00
nop
.byte $eb
cpx @w$0000
sbc @w$0000
inc @w$0000
.byte $ef
beq L11CD
L11CD sbc ($00),y
sbc ($00)
.byte $f3
.byte $f4,$00
sbc $00,x
inc $00,x
.byte $f7
sed
sbc $0000,y
plx
.byte $fb
.byte $fc,$00,$00
sbc @w$0000,x
inc @w$0000,x
.byte $ff

View File

@ -0,0 +1,33 @@
;Project file was edited to get all big-endian data types.
.cpu "6502"
* = $1000
rts
.byte $11
.word $1122
.long $112233
.dword $11223344
.byte $11
.byte $11,$22
.byte $11,$22,$33
.byte $11,$22,$33,$44
.fill 2,$00
.byte $80
.fill 3,$00
.byte $80
.fill 4,$00
.byte $80
.fill 5,$00
.byte $80
.fill 256,$00
.byte $80
.fill 257,$cc
.byte $11
.byte $80
.byte $11,$22,$33,$44,$55,$66,$77,$88,$99,$00
.byte $80
LABEL .byte $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff ;comment
.byte $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff
.byte $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff
.byte $ff,$ee,$dd,$cc,$bb,$aa,$99,$88,$77,$66,$55,$44,$33,$22,$11,$00
.byte $80

View File

@ -0,0 +1,151 @@
;Project file was edited to get zero-length strings and reverse DCI.
.cpu "6502"
* = $1000
rts
.text "low ASCII str"
.byte $80
.byte $e8,$e9,$e7,$e8,$a0,$c1,$d3,$c3,$c9,$c9,$a0,$f3,$f4,$f2
.byte $80
.text "'low'quoted",$22,"''text"
.byte $80
.byte $a2,$e8,$e9,$e7,$e8,$a2,$f1,$f5,$ef,$f4,$e5,$e4,$a7,$a2,$a2,$f4
.byte $e5,$f8,$f4
.byte $80
.text "01234567890123456789012345678901234567890123456789012345678901"
.text "234567890123456789"
.byte $80
.text "0123456789012345678901234567890123456789012345678901234567'''"
.byte $80
.text "01234567890123456789012345678901234567890123456789012345678'''"
.byte $80
.text "012345678901234567890123456789012345678901234567890123456789''"
.text "'"
.byte $80
.text "0123456789012345678901234567890123456789012345678901234567890'"
.text "''"
.byte $80
.text "01234567890123456789012345678901234567890123456789012345678901"
.text "'''"
.byte $80
.text "012345678901234567890123456789012345678901234567890167",$22,$22
.text $22
.byte $80
.text "0123456789012345678901234567890123456789012345678901678",$22
.text $22,$22
.byte $80
.text "01234567890123456789012345678901234567890123456789016789",$22
.text $22,$22
.byte $80
.text "012345678901234567890123456789012345678901234567890167890",$22
.text $22,$22
.byte $80
.text "0123456789012345678901234567890123456789012345678901678901",$22
.text $22,$22
.byte $81
.fill 62,$aa
.byte $80
.fill 96,$aa
.byte $81
.text "ver IICSA wol"
.byte $80
.byte $f6,$e5,$f2,$a0,$c9,$c9,$c3,$d3,$c1,$a0,$e8,$e7,$e9,$e8
.byte $80
.text ".eeht rof sllot ti ;sllot lleb eht mohw rof wonk ot dnes reven"
.text " erofereht dna ,dniknam ni devlovni ma I esuaceb ,em sehsinimi"
.text "d htaed snam ynA .erew nwo eniht fo ro sdneirf yht fo ronam a"
.text " fi sa llew sA .erew yrotnomorp a fi sa llew sA .ssel eht si e"
.text "poruE ,aes eht yb yawa dehsaw eb dolc a fI .niam eht fo trap "
.text "a ,tnenitnoc eht fo eceip a si nam yreve ;flesti fo eritne ,dn"
.text "alsi na si nam oN"
.byte $81
.null ""
.byte $80
.null "low ASCII strz"
.byte $80
.byte $e8,$e9,$e7,$e8,$a0,$c1,$d3,$c3,$c9,$c9,$a0,$f3,$f4,$f2,$fa,$00
.byte $80
.text "'low'quoted",$22,"''text",$00
.byte $80
.byte $a2,$e8,$e9,$e7,$e8,$a2,$f1,$f5,$ef,$f4,$e5,$e4,$a7,$a2,$a2,$f4
.byte $e5,$f8,$f4,$00
.byte $80
.text "012345678901234567890123456789012345678901234567890123456789''"
.text "'",$00
.byte $80
.text "01234567890123456789012345678901234567890123456789012345678901"
.text "234567890123456789",$00
.byte $81
.ptext ""
.byte $80
.ptext "low ASCII str1"
.byte $80
.byte $0f,$e8,$e9,$e7,$e8,$a0,$c1,$d3,$c3,$c9,$c9,$a0,$f3,$f4,$f2,$b1
.byte $80
.text $12,"'low'quoted",$22,"''text"
.byte $80
.byte $13,$a2,$e8,$e9,$e7,$e8,$a2,$f1,$f5,$ef,$f4,$e5,$e4,$a7,$a2,$a2
.byte $f4,$e5,$f8,$f4
.byte $80
.text $3f,"0123456789012345678901234567890123456789012345678901234567"
.text "89'''"
.byte $80
.text $50,"0123456789012345678901234567890123456789012345678901234567"
.text "8901234567890123456789"
.byte $81
.text $00,$00
.byte $80
.text $0e,$00,"low ASCII str2"
.byte $80
.byte $0f,$00,$e8,$e9,$e7,$e8,$a0,$c1,$d3,$c3,$c9,$c9,$a0,$f3,$f4,$f2
.byte $b2
.byte $80
.text $12,$00,"'low'quoted",$22,"''text"
.byte $80
.byte $13,$00,$a2,$e8,$e9,$e7,$e8,$a2,$f1,$f5,$ef,$f4,$e5,$e4,$a7,$a2
.byte $a2,$f4,$e5,$f8,$f4
.byte $80
.text $3f,$00,"012345678901234567890123456789012345678901234567890123"
.text "456789'''"
.byte $80
.text $50,$00,"012345678901234567890123456789012345678901234567890123"
.text "45678901234567890123456789"
.byte $80
.text $85,$01,"No man is an island, entire of itself; every man is a "
.text "piece of the continent, a part of the main. If a clod be wash"
.text "ed away by the sea, Europe is the less. As well as if a promon"
.text "tory were. As well as if a manor of thy friends or of thine ow"
.text "n were. Any mans death diminishes me, because I am involved i"
.text "n mankind, and therefore never send to know for whom the bell "
.text "tolls; it tolls for thee."
.byte $81
.text "low ASCII dc",$e9
.byte $80
.byte $e8,$e9,$e7,$e8,$a0,$c1,$d3,$c3,$c9,$c9,$a0,$e4,$e3,$69
.byte $80
.text "'low'quoted",$22,"''tex",$f4
.byte $80
.byte $a2,$e8,$e9,$e7,$e8,$a2,$f1,$f5,$ef,$f4,$e5,$e4,$a7,$a2,$a2,$f4
.byte $e5,$f8,$74
.byte $80
.text "012345678901234567890123456789012345678901234567890123456789''"
.text $a7
.byte $80
.text "01234567890123456789012345678901234567890123456789012345678901"
.text "23456789012345678",$b9
.byte $81
.text $f2,"icd IICSA wol"
.byte $80
.byte $72,$e9,$e3,$e4,$a0,$c9,$c9,$c3,$d3,$c1,$a0,$e8,$e7,$e9,$e8
.byte $80
.text $b9,"8765432109876543210987654321098765432109876543210987654321"
.text "098765432109876543210"
.byte $80
.text $ae,"eeht rof sllot ti ;sllot lleb eht mohw rof wonk ot dnes re"
.text "ven erofereht dna ,dniknam ni devlovni ma I esuaceb ,em sehsin"
.text "imid htaed snam ynA .erew nwo eniht fo ro sdneirf yht fo rona"
.text "m a fi sa llew sA .erew yrotnomorp a fi sa llew sA .ssel eht s"
.text "i eporuE ,aes eht yb yawa dehsaw eb dolc a fI .niam eht fo tr"
.text "ap a ,tnenitnoc eht fo eceip a si nam yreve ;flesti fo eritne "
.text ",dnalsi na si nam oN"
.byte $81

View File

@ -0,0 +1,65 @@
;Project file was edited for some ASCII operands.
.cpu "65816"
* = $1000
.as
.xs
clc
xce
sep #$30
lda $01
lda $0102
lda $010203
lda 1
lda 258
lda 66051
lda %00000001
lda %0000000100000010
lda %000000010000001000000011
bra skipdata
.byte $01
.word $0201
.long $030201
.dword $04030201
.byte 1
.word 513
.long 197121
.dword 67305985
.byte %00000001
.word %0000001000000001
.long %000000110000001000000001
.dword %00000100000000110000001000000001
skipdata lda #'h'
lda 'h'
lda @w'h'
lda @l'h'
lda #$1f
lda #' '
lda #'~'
lda #$7f
lda #$80
lda #$9f
lda #$a0
lda #$fe
lda #$ff
rep #'0'
.al
.xl
lda #'h'
lda #$c8
lda #$6868
rts
more_ascii .byte 'h'
.byte $80
.word $6868
.byte $80
.word skipdata
.long skipdata
.byte $10,$3f
.byte <more_ascii
.byte >more_ascii
.word more_ascii
.long more_ascii
.byte $10,$68

View File

@ -0,0 +1,123 @@
.cpu "65816"
* = $1000
.as
.xs
clc
xce
sep #$ff
jsr L1100
jsr L1107
jmp L2000
.logical $1100
L1100 bit L1100
L1103 lda #$11
ldx #$11
L1107 ldy #$11
per L1103
bra L1103
.here
.logical $1100
L1100_0 bit L1100_0
lda #$22
L1105 ldx #$22
ldy #$22
per L1105
jmp L1105
.here
.logical $1100
L1100_1 bit L1100_1
lda #$33
ldx #$33
L1107_0 ldy #$33
per L1107_0
bra L1107_0
.here
.logical $2000
L2000 bit L2000
beq $2018
bra L2020
.here
.logical $2020
L2020 bit L2020
beq offend+1
brl L2080
offend nop
.here
.logical $2080
L2080 bit L2080
lda offend
jsr offend
lda offend+1
jsr offend+1
lda $207f
jsr $207f
lda L2080
jsr L2080
lda $00
beq L2100
.byte $ad
.here
.logical $2100
L2100 nop
nop
jmp L3000
.here
.logical $2800
.byte $00
.byte $28
.fill 14,$00
.here
.logical $2820
.fill 18,$00
.here
.logical $3000
L3000 bit L3000
lda #$44
ldx #$44
ldy #$44
brl fwd
ulabel .byte $00
.byte $01
.here
.logical $3100
L3100 .byte $02
fwd bit fwd
lda ulabel
lda ulabel+1
lda ulabel+2
lda $300f
lda L3100
beq L3182
.byte $ea
.byte $ea
.here
.logical $3180
.byte $00
.byte $01
L3182 bit L3182
lda label1
lda label1+1
lda label1+112
bra L3200
label1 .byte $ea
.byte $ea
.here
.logical $3200
L3200 bit L3200
.byte $00
.byte $01
.here

View File

@ -0,0 +1,77 @@
.cpu "65816"
longsym = $123456
* = $1000
.as
.xs
clc
xce
sep #$30
jmp L0000
.logical $0000
L0000 bit @wL0000
L0003 lda L0000
lda L0003
bne LFFC3
bmi $ffc3
per LFFC3
bcc L0016
brl L0080
lodat .byte $00
.byte $01
.byte $02
L0016 lda lodat+1
brl LFFC0
.here
.logical $0080
L0080 bit @wL0080
jml L440000
.here
.logical $ffc0
LFFC0 bit LFFC0
LFFC3 brl L0003
.here
.logical $440000
L440000 cmp L440000
L440004 lda L440000
lda @wL440000 & $ffff
lda L0000
bmi L440004
per high44
bne high44
brl L44FFC0
dat44 .word dat44 & $ffff
.long dat44
.here
.logical $44ffc0
L44FFC0 cmp L44FFC0
high44 beq L44FFCB
bmi L440004
brl L440004
L44FFCB jml L2000
.here
.logical $2000
L2000 bit L2000
pea dat44 & $ffff
pea dat44 >> 16
bne L200E
jml [lodat]
L200E nop
jsr j2
j2 jsr j2+3
jsr j2-3
jsl longsym
rts
.here

View File

@ -0,0 +1,60 @@
.cpu "65816"
* = $1000
.as
.xs
load11 lda #$11
L1002 ldx #$22
load33 ldy #$33
L1006 lda #$44
predat bra L1042
.word $0123
dat1 .word $4567
.word $89ab
L1010 .word $cdef
L1012 .word $0011
L1014 .word $2233
.byte $80
.text "The quick brown fox"
.byte $80
.word L1042
.word L1041
.word L1042+1
fill0 .fill 16,$00
L1041 .byte $80
L1042 lda predat+2
lda L1041
asl dat1
rol dat1+2
ror L1010
and L1012
ora L1014
lda fill0
sta fill0+4
lda fill0+8
sta fill0+12
jsr L1002
lda L1006
L1069 pea L1069-1
per L1069-1
lda L1069+1
lda L1069+2
lda #$ea
L1077 sta L1077
L107A sta L107A+1
sta $107f
brl L2002
.byte $80
dat81 .byte $81
.logical $2000
L2000 .byte $82
.byte $83
L2002 bit L2002
lda dat81
lda L2000
rts
.here

View File

@ -0,0 +1,35 @@
.cpu "6502"
* = $1000
.byte $03
.byte $02
L1002 bit L1002
.byte $2c
lda #$11
nop
.byte $2c
L100A ldx #$ff
nop
jsr L100A
nop
.byte $2c
L1012 ldx #$ff
nop
jsr L1012
jsr $2456
L101B .dword $22a211a9
jsr L101B
jsr L1028
jsr $2456
L1028 .dword $44a233a9
jsr L1037
jsr L103A
nop
lda $2456
rts
L1037 jsr $2456
L103A lda #$55
ldx #$66
rts

View File

@ -0,0 +1,58 @@
.cpu "65816"
REALLYLONGLABELNAME = $8888 ;that's a long name
* = $1000
.as
.xs
nop
start lda _L100D
lda nextglob
lda pastglob
lda _L100E
_L100D nop
_L100E nop
nextglob
nop
pastglob
nop
lda nlocal
nlocal lda #$11
reach1G nop
lda reach1G+1
lda _reach2+2
_reach2 nop
reach3G nop
_reach4 nop
lda _reach4-2
lda $00
beq _L102D
jsr _reach4
jsr start
_L102D lda #$22
lda gtest2
gtest1 nop
lda gtest3
gtest2 nop
gtest3 nop
lda #$33
lda $1041
topglob nop
lda _L1043
nop
nop
_L1043 nop
lda #$44
_globalnm
jsr _L104A
nop
_L104A nop
nop
nglobal nop
globlat jsr nglobal
bra end
end nop
EXCESSIVELY_LONG_LABEL
lda REALLYLONGLABELNAME
rts

View File

@ -0,0 +1,73 @@
;***************************************
;* Old school boxed output header. *
;* Brk *
;* multiple lines yay. How about a *
;* hy-phenated word? *
;* Looonglonglonglonglonglonglonglongl *
;* onglonglongword. *
;***************************************
;* Throw in a line divider. These *
;* aren't: *
;* *! *
;* * *
;* &XYZ *
;* *
;***************************************
.cpu "6502"
plataddr = $3000 ;address only in platform file
;Short, unboxed comment here!!
; Two spaces after. More hyp-
;hens?
* = $1000
lda #$01 ;Comment!
;Comment rulers can be helpful in findin the edges of notes. Comments are hyph-
;enatingly fun. Like the note, this goes out to 80 columns.
lda #$02 ;&another comment with &&s!
;Down to 64 columns this time. Why 64? Why not 64. A rose, by
;any other name, would break the line at the same place. Or hy-
;phen split.
lda #$03
;Ah, the classic 40-column limitation...
;brings back memories. Of, you know, h-
;yphenated things.
lda #$04
;Thirty columns. 'cause forty
;felt like too many. Oh, hyp-
;henation!
lda #$05
;*******************************************************************************
;* Short box comment, 80 cols. *
;*******************************************************************************
lda #$06
;***************************************************************
;* *
;* Choppy *
;* *
;* box *
;* *
;* comment *
;* *
;* 64 cols *
;* *
;***************************************************************
lda #$07
;*****************************
;* Some non-ASCII stuff: *
;* †•<E280A0>␇ *
;*****************************
lda #$08
lda #$09
lda #$0a
lda #$0b
lda #$0c
lda #$0d
lda #$0e
lda #$0f
bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
rts
bytes .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ;Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped.
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f

View File

@ -98,6 +98,7 @@
<Compile Include="AppSettings.cs" />
<Compile Include="AsmGen\AsmCc65.cs" />
<Compile Include="AsmGen\AsmMerlin32.cs" />
<Compile Include="AsmGen\AsmTass64.cs" />
<Compile Include="AsmGen\AssemblerConfig.cs" />
<Compile Include="AsmGen\AssemblerVersion.cs" />
<Compile Include="AsmGen\GenAndAsm.cs">