From 459cde40c4a6e97570cf4ccf5c2fab1bfe87130e Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 10 Jul 2025 11:17:41 -0700 Subject: [PATCH] Fix Merlin 32 DP op generation Most assemblers treat '<' and '>' as byte-select operators. Merlin 32 treats them as shift operators, making '<' effectively a no-op. A mask is applied based on the length implied by the opcode or pseudo-op, e.g. "DFB = $100, the lack of masking will cause it be treated as absolute. There is currently no other mechanism to force the use of a direct-page opcode. The only recourse is to append "&$ff" to the operand, so the assembler knows that it can be handled as a DP op. The code generator has been updated to add "&$ff" where needed, based on the label's value. Unfortunately the assembler doesn't accept this for certain specific addressing modes; this appears to be a bug. The relevant test cases (2003x-labels-and-symbols) have been updated to exercise these situations. The current test projects side-step the failing assembler behavior by using a DP label instead. These should be changed to correctly exercise the full behavior, with the code generator outputting the instructions as raw hex values to work around bugs. There are some deliberately broken things (like a duplicate label) in the 20030 case that were copied into the 20032 case when it was created. For ease of editing these have been removed from 20032. (issue #170) --- Asm65/Formatter.cs | 57 +- Asm65/OpDef.cs | 2 +- SourceGen/AsmGen/AsmMerlin32.cs | 7 +- SourceGen/AsmGen/GenCommon.cs | 19 +- SourceGen/AsmGen/IGenerator.cs | 6 + SourceGen/SGTestData/20030-labels-and-symbols | Bin 452 -> 460 bytes .../SGTestData/20030-labels-and-symbols.dis65 | 36 +- SourceGen/SGTestData/20032-labels-and-symbols | Bin 695 -> 729 bytes .../SGTestData/20032-labels-and-symbols.dis65 | 665 ++++++++++++++---- .../20030-labels-and-symbols_64tass.S | 4 + .../Expected/20030-labels-and-symbols_acme.S | 4 + .../Expected/20030-labels-and-symbols_cc65.S | 4 + .../20030-labels-and-symbols_merlin32.S | 4 + .../20032-labels-and-symbols_64tass.S | 25 +- .../Expected/20032-labels-and-symbols_acme.S | 3 +- .../Expected/20032-labels-and-symbols_cc65.S | 25 +- .../20032-labels-and-symbols_merlin32.S | 25 +- .../20170-external-symbols_merlin32.S | 2 +- .../Source/20030-labels-and-symbols.S | 4 + .../Source/20032-labels-and-symbols.S | 23 + docs/sgmanual/codegen.html | 7 +- 21 files changed, 726 insertions(+), 196 deletions(-) diff --git a/Asm65/Formatter.cs b/Asm65/Formatter.cs index 3734d73..a64e526 100644 --- a/Asm65/Formatter.cs +++ b/Asm65/Formatter.cs @@ -88,6 +88,8 @@ namespace Asm65 { /// String to prefix operand with to force DP addressing. public string ForceDirectOperandPrefix { get; set; } = string.Empty; + /// String to suffix operand with to force DP addressing. + public string ForceDirectOperandSuffix { get; set; } = string.Empty; /// String to suffix opcode with to force abs addressing. public string ForceAbsOpcodeSuffix { get; set; } = string.Empty; /// String to prefix operand with to force abs addressing. @@ -172,6 +174,7 @@ namespace Asm65 { BankSelectBackQuote = src.BankSelectBackQuote; ForceDirectOperandPrefix = src.ForceDirectOperandPrefix; + ForceDirectOperandSuffix = src.ForceDirectOperandSuffix; ForceAbsOpcodeSuffix = src.ForceAbsOpcodeSuffix; ForceAbsOperandPrefix = src.ForceAbsOperandPrefix; ForceDirectOpcodeSuffix = src.ForceDirectOpcodeSuffix; @@ -915,19 +918,23 @@ namespace Asm65 { private string GenerateOperandFormat(OpDef.AddressMode addrMode, OpDef.WidthDisambiguation wdis) { string fmt; - string wdisStr = string.Empty; + string pfxStr = string.Empty; + string dpsfxStr = string.Empty; if (wdis == OpDef.WidthDisambiguation.ForceDirect) { if (!string.IsNullOrEmpty(mFormatConfig.ForceDirectOperandPrefix)) { - wdisStr = mFormatConfig.ForceDirectOperandPrefix; + pfxStr = mFormatConfig.ForceDirectOperandPrefix; + } + if (!string.IsNullOrEmpty(mFormatConfig.ForceDirectOperandSuffix)) { + dpsfxStr = mFormatConfig.ForceDirectOperandSuffix; } } else if (wdis == OpDef.WidthDisambiguation.ForceAbs) { if (!string.IsNullOrEmpty(mFormatConfig.ForceAbsOperandPrefix)) { - wdisStr = mFormatConfig.ForceAbsOperandPrefix; + pfxStr = mFormatConfig.ForceAbsOperandPrefix; } } else if (wdis == OpDef.WidthDisambiguation.ForceLong) { if (!string.IsNullOrEmpty(mFormatConfig.ForceLongOperandPrefix)) { - wdisStr = mFormatConfig.ForceLongOperandPrefix; + pfxStr = mFormatConfig.ForceLongOperandPrefix; } } else if (wdis == OpDef.WidthDisambiguation.ForceLongMaybe) { // Don't add a width disambiguator to an operand that is unambiguously long. @@ -940,35 +947,29 @@ namespace Asm65 { case AddressMode.AbsLong: case AddressMode.BlockMove: case AddressMode.StackAbs: - case AddressMode.DP: - case AddressMode.DPPCRel: // BBR/BBS + case AddressMode.DPPCRel: // BBR/BBS (syntax varies) case AddressMode.PCRel: case AddressMode.PCRelLong: // BRL case AddressMode.StackInt: // COP and two-byte BRK case AddressMode.StackPCRelLong: // PER case AddressMode.WDM: - fmt = wdisStr + "{0}"; + fmt = pfxStr + "{0}"; break; case AddressMode.AbsIndexX: case AddressMode.AbsIndexXLong: - case AddressMode.DPIndexX: - fmt = wdisStr + "{0}," + mXregChar; + fmt = pfxStr + "{0}," + mXregChar; break; - case AddressMode.DPIndexY: case AddressMode.AbsIndexY: - fmt = wdisStr + "{0}," + mYregChar; + fmt = pfxStr + "{0}," + mYregChar; break; case AddressMode.AbsIndexXInd: - case AddressMode.DPIndexXInd: - fmt = wdisStr + "({0}," + mXregChar + ")"; + fmt = pfxStr + "({0}," + mXregChar + ")"; break; case AddressMode.AbsInd: - case AddressMode.DPInd: case AddressMode.StackDPInd: // PEI fmt = "({0})"; break; case AddressMode.AbsIndLong: - case AddressMode.DPIndLong: // IIgs monitor uses "()" for AbsIndLong, E&L says "[]". Assemblers // seem to expect the latter. fmt = "[{0}]"; @@ -976,11 +977,31 @@ namespace Asm65 { case AddressMode.Acc: fmt = mAccChar; break; + case AddressMode.DP: + fmt = pfxStr + "{0}" + dpsfxStr; + break; + case AddressMode.DPIndexX: + fmt = pfxStr + "{0}" + dpsfxStr + "," + mXregChar; + break; + case AddressMode.DPIndexY: + fmt = pfxStr + "{0}" + dpsfxStr + "," + mYregChar; + break; + case AddressMode.DPIndexXInd: + fmt = pfxStr + "({0}" + dpsfxStr + "," + mXregChar + ")"; + break; + case AddressMode.DPInd: + fmt = "({0}" + dpsfxStr + ")"; + break; + case AddressMode.DPIndLong: + // IIgs monitor uses "()" for AbsIndLong, E&L says "[]". Assemblers + // seem to expect the latter. + fmt = "[{0}" + dpsfxStr + "]"; + break; case AddressMode.DPIndIndexY: - fmt = "({0})," + mYregChar; + fmt = "({0}" + dpsfxStr + ")," + mYregChar; break; case AddressMode.DPIndIndexYLong: - fmt = "[{0}]," + mYregChar; + fmt = "[{0}" + dpsfxStr + "]," + mYregChar; break; case AddressMode.Imm: case AddressMode.ImmLongA: @@ -1021,7 +1042,7 @@ namespace Asm65 { /// Formatted string. public string FormatOperand(OpDef op, string contents, OpDef.WidthDisambiguation wdis) { Debug.Assert(((int)op.AddrMode & 0xff) == (int) op.AddrMode); - int key = (int) op.AddrMode | ((int)wdis << 8); + int key = (int) op.AddrMode | ((int)wdis << 8); // form unique cache key if (!mOperandFormats.TryGetValue(key, out string format)) { format = mOperandFormats[key] = GenerateOperandFormat(op.AddrMode, wdis); diff --git a/Asm65/OpDef.cs b/Asm65/OpDef.cs index ba3488e..ecb4905 100644 --- a/Asm65/OpDef.cs +++ b/Asm65/OpDef.cs @@ -124,7 +124,7 @@ namespace Asm65 { /// public enum WidthDisambiguation : byte { None = 0, - ForceDirect, // only needed for forward DP label refs in single-pass assemblers + ForceDirect, // mainly needed for forward DP label refs in single-pass assemblers ForceAbs, ForceLong, ForceLongMaybe // add opcode suffix but not operand prefix diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs index b3a6d2f..944ea3e 100644 --- a/SourceGen/AsmGen/AsmMerlin32.cs +++ b/SourceGen/AsmGen/AsmMerlin32.cs @@ -178,6 +178,7 @@ namespace SourceGen.AsmGen { Quirks.NoPcRelBankWrap = true; Quirks.TracksSepRepNotEmu = true; + Quirks.ByteSelectionIsShift = true; mWorkDirectory = workDirectory; mFileNameBase = fileNameBase; @@ -200,6 +201,7 @@ namespace SourceGen.AsmGen { config.ForceAbsOpcodeSuffix = ":"; config.ForceLongOpcodeSuffix = "l"; config.ForceDirectOperandPrefix = string.Empty; + config.ForceDirectOperandSuffix = "&$ff"; config.ForceAbsOperandPrefix = string.Empty; config.ForceLongOperandPrefix = string.Empty; config.LocalVariableLabelPrefix = "]"; @@ -841,9 +843,10 @@ namespace SourceGen.AsmGen { } // Stdout: "C:\Src\WorkBench\Merlin32.exe v 1.0, (c) Brutal Deluxe ..." - // "C:\Src\WorkBench\Merlin32.exe v 1.2 beta 1, (c) Brutal Deluxe ..." + // "... Merlin32.exe v 1.2 beta 1, (c) Brutal Deluxe ..." + // "... Merlin32_119.exe v1.1.9, (c) Brutal Deluxe ..." // Other platforms may not have the ".exe". Start at first occurrence of " v ". - private static string sVersionPattern = @" v (\d.\d)( [^,]+)?,"; + private static string sVersionPattern = @" v *(\d.\d)(.\d)?( [^,]+)?,"; private static Regex sVersionRegex = new Regex(sVersionPattern); // IAssembler diff --git a/SourceGen/AsmGen/GenCommon.cs b/SourceGen/AsmGen/GenCommon.cs index 51f69d8..81a606d 100644 --- a/SourceGen/AsmGen/GenCommon.cs +++ b/SourceGen/AsmGen/GenCommon.cs @@ -240,12 +240,13 @@ namespace SourceGen.AsmGen { if (op.IsWidthPotentiallyAmbiguous) { wdis = OpDef.GetWidthDisambiguation(instrLen, operand); } + // Some DP addressing modes are ambiguous to one-pass assemblers. if (gen.Quirks.SinglePassAssembler && wdis == OpDef.WidthDisambiguation.None && (op.AddrMode == OpDef.AddressMode.DP || - op.AddrMode == OpDef.AddressMode.DPIndexX) || - op.AddrMode == OpDef.AddressMode.DPIndexY) { + op.AddrMode == OpDef.AddressMode.DPIndexX || + op.AddrMode == OpDef.AddressMode.DPIndexY)) { // Could be a forward reference to a direct-page label. For ACME, we don't - // care if it's forward or not. + // care if it's forward or not, only that it's referencing a user label. if ((gen.Quirks.SinglePassNoLabelCorrection && IsLabelReference(gen, offset)) || IsForwardLabelReference(gen, offset)) { wdis = OpDef.WidthDisambiguation.ForceDirect; @@ -343,6 +344,18 @@ namespace SourceGen.AsmGen { formattedOperand = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable, lvLookup, gen.Localizer.LabelMap, dfd, offset, operandForSymbol, operandLen, opFlags); + // Handle special case for DP args with non-DP labels. + if (gen.Quirks.ByteSelectionIsShift && wdis == OpDef.WidthDisambiguation.None && + op.IsDirectPageInstruction && dfd.SymbolRef != null) { + // The '<' operator is effectively a no-op, so "LDA 0xff) { + wdis = OpDef.WidthDisambiguation.ForceDirect; + } + } } } else { // Show operand value in hex. diff --git a/SourceGen/AsmGen/IGenerator.cs b/SourceGen/AsmGen/IGenerator.cs index d838c1d..07ac6b9 100644 --- a/SourceGen/AsmGen/IGenerator.cs +++ b/SourceGen/AsmGen/IGenerator.cs @@ -280,6 +280,12 @@ namespace SourceGen.AsmGen { /// track the emulation bit? /// public bool TracksSepRepNotEmu { get; set; } + + /// + /// Do the byte selection operators ('<', '>', '^') act as shifts that don't + /// reduce the value to 8 bits? + /// + public bool ByteSelectionIsShift { get; set; } } /// diff --git a/SourceGen/SGTestData/20030-labels-and-symbols b/SourceGen/SGTestData/20030-labels-and-symbols index 29a9d0a2d10ac9c75a2e7fd2fc4f0a3abf3d41cb..1aa5f1c0cc0a604dd0f1fbe0c14ab535fba3aaf8 100644 GIT binary patch delta 17 ZcmX@Ye1>_$VMflSLQ6%q3T+fm002Fv26F%a delta 9 QcmX@Ze1v(!VMfLT027=8YybcN diff --git a/SourceGen/SGTestData/20030-labels-and-symbols.dis65 b/SourceGen/SGTestData/20030-labels-and-symbols.dis65 index 5d44e18..6f29e05 100644 --- a/SourceGen/SGTestData/20030-labels-and-symbols.dis65 +++ b/SourceGen/SGTestData/20030-labels-and-symbols.dis65 @@ -1,8 +1,8 @@ ### 6502bench SourceGen dis65 v1.0 ### { "_ContentVersion":3, -"FileDataLength":452, -"FileDataCrc32":-1349239236, +"FileDataLength":460, +"FileDataCrc32":-736313654, "ProjectProps":{ "CpuName":"6502", "IncludeUndocumentedInstr":false, @@ -602,7 +602,37 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"BMI", -"Part":"Low"}}}, +"Part":"Low"}}, + +"451":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"targ", +"Part":"Low"}}, +"453":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"targ", +"Part":"Low"}}, +"455":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"targ", +"Part":"Low"}}, +"457":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"targ", +"Part":"Low"}} +}, "LvTables":{ }, diff --git a/SourceGen/SGTestData/20032-labels-and-symbols b/SourceGen/SGTestData/20032-labels-and-symbols index a200c62e91cd8a28de3ff5baa42ff17824d08e13..31a2035150e7c6864c726f95a72d736ef5410045 100644 GIT binary patch delta 43 zcmV+`0M!4t1=$6#wgMySt)CI4pQWI(p|PU3qo<^`rJ>ZhrvRnEvB9>&w8PZV>R=H4 B8YKV# delta 9 Qcmcb~x}9~yHYUad0284DWB>pF diff --git a/SourceGen/SGTestData/20032-labels-and-symbols.dis65 b/SourceGen/SGTestData/20032-labels-and-symbols.dis65 index 444cc0d..243dcca 100644 --- a/SourceGen/SGTestData/20032-labels-and-symbols.dis65 +++ b/SourceGen/SGTestData/20032-labels-and-symbols.dis65 @@ -1,8 +1,8 @@ ### 6502bench SourceGen dis65 v1.0 ### { -"_ContentVersion":4, -"FileDataLength":695, -"FileDataCrc32":1242388944, +"_ContentVersion":6, +"FileDataLength":729, +"FileDataCrc32":-707037586, "ProjectProps":{ "CpuName":"65816", "IncludeUndocumentedInstr":false, @@ -27,7 +27,8 @@ "Length":1, "Format":"NumericLE", "SubFormat":"Hex", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "Comment":"opcode mnemonic", "HasWidth":false, @@ -44,7 +45,8 @@ "Length":1, "Format":"NumericLE", "SubFormat":"Decimal", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "Comment":"should be replaced by user label", "HasWidth":false, @@ -61,7 +63,8 @@ "Length":1, "Format":"NumericLE", "SubFormat":"Hex", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "Comment":"same val as projalso", "HasWidth":false, @@ -78,7 +81,8 @@ "Length":1, "Format":"NumericLE", "SubFormat":"Hex", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "Comment":"same val as projalso", "HasWidth":false, @@ -95,7 +99,8 @@ "Length":1, "Format":"NumericLE", "SubFormat":"Hex", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "Comment":"replaces platform symbol", "HasWidth":false, @@ -112,7 +117,8 @@ "Length":1, "Format":"NumericLE", "SubFormat":"Hex", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "Comment":"32-bit constant test", "HasWidth":false, @@ -126,11 +132,21 @@ "AddressMap":[{ "Offset":0, -"Addr":74565}, +"Addr":74565, +"Length":-1024, +"PreLabel":"", +"DisallowInward":false, +"DisallowOutward":false, +"IsRelative":false}, { "Offset":279, -"Addr":4096}], +"Addr":4096, +"Length":-1024, +"PreLabel":"", +"DisallowInward":false, +"DisallowOutward":false, +"IsRelative":false}], "TypeHints":[{ "Low":0, "High":0, @@ -145,6 +161,7 @@ "LongComments":{ "-2147483647":{ "Text":"Project was edited to add a label in the middle of a dense hex region, and add a duplicate label.", +"IsFancy":false, "BoxMode":false, "MaxWidth":80, "BackgroundColor":0}}, @@ -223,25 +240,18 @@ "Type":"LocalOrGlobalAddr", "LabelAnno":"None"}, -"358":{ -"Label":"calls", -"Value":4175, +"694":{ +"Label":"before", +"Value":4511, "Source":"User", -"Type":"LocalOrGlobalAddr", +"Type":"GlobalAddr", "LabelAnno":"None"}, -"410":{ -"Label":"badmid", -"Value":4227, +"721":{ +"Label":"after", +"Value":4538, "Source":"User", -"Type":"LocalOrGlobalAddr", -"LabelAnno":"None"}, - -"362":{ -"Label":"badmidi", -"Value":4179, -"Source":"User", -"Type":"LocalOrGlobalAddr", +"Type":"GlobalAddr", "LabelAnno":"None"}}, "OperandFormats":{ @@ -251,7 +261,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "6":{ "Length":2, @@ -259,7 +271,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "8":{ "Length":2, @@ -267,7 +281,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "10":{ "Length":2, @@ -275,7 +291,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "12":{ "Length":2, @@ -283,7 +301,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "14":{ "Length":2, @@ -291,7 +311,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "16":{ "Length":2, @@ -299,7 +321,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "18":{ "Length":2, @@ -307,7 +331,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "20":{ "Length":2, @@ -315,7 +341,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "22":{ "Length":2, @@ -323,7 +351,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "24":{ "Length":2, @@ -331,7 +361,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "26":{ "Length":2, @@ -339,7 +371,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "28":{ "Length":2, @@ -347,7 +381,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "30":{ "Length":2, @@ -355,7 +391,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "47":{ "Length":3, @@ -363,7 +401,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "50":{ "Length":3, @@ -371,7 +411,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "53":{ "Length":3, @@ -379,7 +421,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "56":{ "Length":3, @@ -387,7 +431,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "59":{ "Length":3, @@ -395,7 +441,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "62":{ "Length":2, @@ -403,7 +451,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "64":{ "Length":3, @@ -411,7 +461,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "67":{ "Length":4, @@ -419,7 +471,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "71":{ "Length":3, @@ -427,7 +481,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "74":{ "Length":4, @@ -435,7 +491,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "78":{ "Length":3, @@ -443,7 +501,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "81":{ "Length":4, @@ -451,7 +511,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "85":{ "Length":3, @@ -459,7 +521,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "88":{ "Length":4, @@ -467,7 +531,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "92":{ "Length":3, @@ -475,7 +541,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "95":{ "Length":4, @@ -483,7 +551,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "99":{ "Length":3, @@ -491,7 +561,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "102":{ "Length":4, @@ -499,7 +571,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "106":{ "Length":3, @@ -507,7 +581,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "109":{ "Length":4, @@ -515,7 +591,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "115":{ "Length":3, @@ -523,7 +601,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "118":{ "Length":3, @@ -531,7 +611,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "121":{ "Length":3, @@ -539,7 +621,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "124":{ "Length":3, @@ -547,7 +631,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "127":{ "Length":3, @@ -555,7 +641,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "130":{ "Length":3, @@ -563,7 +651,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "133":{ "Length":3, @@ -571,7 +661,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "136":{ "Length":3, @@ -579,7 +671,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "139":{ "Length":3, @@ -587,7 +681,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "142":{ "Length":3, @@ -595,7 +691,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "145":{ "Length":3, @@ -603,7 +701,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "148":{ "Length":3, @@ -611,7 +711,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "151":{ "Length":3, @@ -619,7 +721,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "154":{ "Length":3, @@ -627,7 +731,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "157":{ "Length":3, @@ -635,7 +741,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "160":{ "Length":3, @@ -643,7 +751,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "163":{ "Length":3, @@ -651,7 +761,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "166":{ "Length":3, @@ -659,7 +771,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "169":{ "Length":3, @@ -667,7 +781,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "174":{ "Length":1, @@ -675,7 +791,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "175":{ "Length":1, @@ -683,7 +801,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "176":{ "Length":1, @@ -691,7 +811,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "177":{ "Length":1, @@ -699,7 +821,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "178":{ "Length":1, @@ -707,7 +831,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "179":{ "Length":1, @@ -715,7 +841,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "180":{ "Length":2, @@ -723,7 +851,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "182":{ "Length":2, @@ -731,7 +861,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "184":{ "Length":2, @@ -739,7 +871,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "186":{ "Length":2, @@ -747,7 +881,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "188":{ "Length":2, @@ -755,7 +891,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absl", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "190":{ "Length":2, @@ -763,7 +901,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "192":{ "Length":2, @@ -771,7 +911,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "194":{ "Length":2, @@ -779,7 +921,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "196":{ "Length":2, @@ -787,7 +931,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "198":{ "Length":2, @@ -795,7 +941,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "200":{ "Length":2, @@ -803,7 +951,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "202":{ "Length":2, @@ -811,7 +961,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "204":{ "Length":2, @@ -819,7 +971,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "206":{ "Length":2, @@ -827,7 +981,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "208":{ "Length":2, @@ -835,7 +991,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "210":{ "Length":2, @@ -843,7 +1001,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "212":{ "Length":3, @@ -851,7 +1011,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "215":{ "Length":3, @@ -859,7 +1021,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "218":{ "Length":3, @@ -867,7 +1031,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "221":{ "Length":3, @@ -875,7 +1041,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "224":{ "Length":3, @@ -883,7 +1051,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "227":{ "Length":3, @@ -891,7 +1061,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "230":{ "Length":4, @@ -899,7 +1071,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"zip", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "234":{ "Length":4, @@ -907,7 +1081,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "238":{ "Length":4, @@ -915,7 +1091,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"absh", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "242":{ "Length":4, @@ -923,7 +1101,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "246":{ "Length":4, @@ -931,7 +1111,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "250":{ "Length":4, @@ -939,7 +1121,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "254":{ "Length":3, @@ -947,7 +1131,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "257":{ "Length":3, @@ -955,7 +1141,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"biggie", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "260":{ "Length":3, @@ -963,19 +1151,23 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"start", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "263":{ "Length":3, "Format":"NumericLE", "SubFormat":"Decimal", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "266":{ "Length":3, "Format":"NumericLE", "SubFormat":"Binary", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "269":{ "Length":3, @@ -983,7 +1175,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"skipdata", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "301":{ "Length":3, @@ -991,7 +1185,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "307":{ "Length":3, @@ -999,7 +1195,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "310":{ "Length":3, @@ -1007,7 +1205,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "316":{ "Length":3, @@ -1015,7 +1215,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "319":{ "Length":2, @@ -1023,7 +1225,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "323":{ "Length":2, @@ -1031,7 +1235,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "325":{ "Length":3, @@ -1039,7 +1245,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "331":{ "Length":3, @@ -1047,7 +1255,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "334":{ "Length":3, @@ -1055,7 +1265,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "340":{ "Length":3, @@ -1063,7 +1275,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "343":{ "Length":4, @@ -1071,7 +1285,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "351":{ "Length":4, @@ -1079,29 +1295,16 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"targ", -"Part":"Low"}}, +"Part":"Low"}, -"388":{ -"Length":3, -"Format":"NumericLE", -"SubFormat":"Symbol", -"SymbolRef":{ -"Label":"badmidi", -"Part":"Low"}}, - -"391":{ -"Length":3, -"Format":"NumericLE", -"SubFormat":"Symbol", -"SymbolRef":{ -"Label":"badmid", -"Part":"Low"}}, +"Extra":null}, "397":{ "Length":112, "Format":"Dense", "SubFormat":"None", -"SymbolRef":null}, +"SymbolRef":null, +"Extra":null}, "677":{ "Length":2, @@ -1109,7 +1312,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"thirty2", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "679":{ "Length":2, @@ -1117,7 +1322,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"thirty2", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "681":{ "Length":2, @@ -1125,7 +1332,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"thirty2", -"Part":"Bank"}}, +"Part":"Bank"}, + +"Extra":null}, "683":{ "Length":2, @@ -1133,7 +1342,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"BMI", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "685":{ "Length":3, @@ -1141,7 +1352,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"thirty2", -"Part":"Low"}}, +"Part":"Low"}, + +"Extra":null}, "688":{ "Length":3, @@ -1149,7 +1362,9 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"thirty2", -"Part":"High"}}, +"Part":"High"}, + +"Extra":null}, "691":{ "Length":3, @@ -1157,7 +1372,149 @@ "SubFormat":"Symbol", "SymbolRef":{ "Label":"thirty2", -"Part":"Bank"}}}, +"Part":"Bank"}, + +"Extra":null}, + +"698":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"700":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"702":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"704":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"706":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"708":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"710":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"712":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"zip", +"Part":"Low"}, + +"Extra":null}, + +"714":{ +"Length":3, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"before", +"Part":"Low"}, + +"Extra":null}, + +"717":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"after", +"Part":"Low"}, + +"Extra":null}, + +"719":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"after", +"Part":"Low"}, + +"Extra":null}, + +"721":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"after", +"Part":"Low"}, + +"Extra":null}, + +"723":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"after", +"Part":"Low"}, + +"Extra":null}, + +"725":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"Symbol", +"SymbolRef":{ +"Label":"zip", +"Part":"Low"}, + +"Extra":null}}, "LvTables":{ }, diff --git a/SourceGen/SGTestData/Expected/20030-labels-and-symbols_64tass.S b/SourceGen/SGTestData/Expected/20030-labels-and-symbols_64tass.S index 7b97c49..a4d241f 100644 --- a/SourceGen/SGTestData/Expected/20030-labels-and-symbols_64tass.S +++ b/SourceGen/SGTestData/Expected/20030-labels-and-symbols_64tass.S @@ -109,6 +109,10 @@ calls jsr L1015 .text "he quick brown fox jumps over the lazy dogs." L1160 adc #BMI1 + lda > 8) & $ffff)+4 lda #thirty2 >> 16 +before nop + lda before + lda > 8 & $ffff +4 lda #thirty2 >> 16 +before: nop + lda before + lda thirty2+$400 lda #^thirty2 +before nop + lda before + lda thirty2 + 1024 lda #^thirty2 +; test direct-page access with a non-DP label, forward and backward, with adjustments +before nop + + lda before + lda [web site] [bug tracker]

+

The history is somewhat complicated, as there are two different versions +of Merlin v1.1, updated by different authors. These are referred to as +the "official" and "forked" versions.

-

Bugs:

+

Bugs (present in v1.0; unclear if/when these have been fixed):

  • PC relative branches don't wrap around at bank boundaries.
  • For some failures, an exit code of zero is returned.
  • @@ -357,6 +360,8 @@ target assembler doesn't handle it.

  • The byte selection operators ('<', '>', '^') are actually word-selection operators, yielding 16-bit values when wide registers are enabled on the 65816.
  • +
  • It's not possible to force direct-page addressing with a modifier. + "&$ff" must be added to the operand.
  • Values loaded into registers are implicitly mod 256 or 65536. There is no need to explicitly mask an expression.
  • The assembler tracks register widths when it sees SEP/REP instructions,