From 835c1c7fe2341421c2c55a8064e66b8f33607021 Mon Sep 17 00:00:00 2001
From: Andy McFadden
Date: Thu, 8 Aug 2019 13:02:01 -0700
Subject: [PATCH] Reverse position on '#' in block move operands
During a discussion with the cc65 developers, I became convinced that
generating "MVN $01,$02" is wrong, and "MVN #$01,#$02" is correct.
64tass, cc65, and Merlin 32 all accept this syntax; only ACME does
not. Operands without a leading '#' should be treated as 24-bit
values, and have the bank byte extracted.
This change updates the on-screen display and assembled output to
include the '#'. The ACME generator uses a Quirk to suppress the
hash mark. (It doesn't currently accept values larger than 8 bits,
so there's no ambiguity.)
---
SourceGen/AsmGen/AsmAcme.cs | 1 +
SourceGen/AsmGen/AsmCc65.cs | 8 +++++---
SourceGen/AsmGen/GenCommon.cs | 8 +++++---
SourceGen/AsmGen/IGenerator.cs | 5 +++++
SourceGen/LineListGen.cs | 6 +++---
SourceGen/RuntimeData/Help/codegen.html | 5 ++---
.../SGTestData/Expected/1000-allops-value-65816_64tass.S | 4 ++--
.../Expected/1000-allops-value-65816_Merlin32.S | 4 ++--
.../SGTestData/Expected/1000-allops-value-65816_cc65.S | 4 ++--
.../SGTestData/Expected/1001-allops-zero-65816_64tass.S | 4 ++--
.../SGTestData/Expected/1001-allops-zero-65816_Merlin32.S | 4 ++--
.../SGTestData/Expected/1001-allops-zero-65816_cc65.S | 4 ++--
.../SGTestData/Expected/2007-labels-and-symbols_64tass.S | 8 ++++----
.../Expected/2007-labels-and-symbols_Merlin32.S | 8 ++++----
.../SGTestData/Expected/2007-labels-and-symbols_cc65.S | 8 ++++----
SourceGen/SGTestData/Expected/2014-label-dp_64tass.S | 4 ++--
SourceGen/SGTestData/Expected/2014-label-dp_Merlin32.S | 4 ++--
SourceGen/SGTestData/Expected/2014-label-dp_cc65.S | 4 ++--
18 files changed, 51 insertions(+), 42 deletions(-)
diff --git a/SourceGen/AsmGen/AsmAcme.cs b/SourceGen/AsmGen/AsmAcme.cs
index bfcb8a9..37d73f2 100644
--- a/SourceGen/AsmGen/AsmAcme.cs
+++ b/SourceGen/AsmGen/AsmAcme.cs
@@ -161,6 +161,7 @@ namespace SourceGen.AsmGen {
Quirks = new AssemblerQuirks();
Quirks.SinglePassAssembler = true;
Quirks.SinglePassNoLabelCorrection = true;
+ Quirks.BlockMoveArgsNoHash = true;
mWorkDirectory = workDirectory;
mFileNameBase = fileNameBase;
diff --git a/SourceGen/AsmGen/AsmCc65.cs b/SourceGen/AsmGen/AsmCc65.cs
index 8db7b0b..a8fd438 100644
--- a/SourceGen/AsmGen/AsmCc65.cs
+++ b/SourceGen/AsmGen/AsmCc65.cs
@@ -149,9 +149,11 @@ namespace SourceGen.AsmGen {
mAsmVersion = V2_18;
}
- // cc65 v2.17: https://github.com/cc65/cc65/issues/717
- // cc65 v2.18: https://github.com/cc65/cc65/issues/925
- Quirks.BlockMoveArgsReversed = true;
+ if (mAsmVersion <= V2_17) {
+ // cc65 v2.17: https://github.com/cc65/cc65/issues/717
+ // see also https://github.com/cc65/cc65/issues/926
+ Quirks.BlockMoveArgsReversed = true;
+ }
// cc65 v2.17: https://github.com/cc65/cc65/issues/754
// still broken in v2.18
diff --git a/SourceGen/AsmGen/GenCommon.cs b/SourceGen/AsmGen/GenCommon.cs
index 5f4cc53..133c87f 100644
--- a/SourceGen/AsmGen/GenCommon.cs
+++ b/SourceGen/AsmGen/GenCommon.cs
@@ -234,7 +234,8 @@ namespace SourceGen.AsmGen {
opstr1 = opstr2;
opstr2 = tmp;
}
- formattedOperand = opstr1 + "," + opstr2;
+ string hash = gen.Quirks.BlockMoveArgsNoHash ? "" : "#";
+ formattedOperand = hash + opstr1 + "," + hash + opstr2;
} else {
formattedOperand = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable,
gen.Localizer.LabelMap, attr.DataDescriptor,
@@ -251,8 +252,9 @@ namespace SourceGen.AsmGen {
arg1 = operand >> 8;
arg2 = operand & 0xff;
}
- formattedOperand = formatter.FormatHexValue(arg1, 2) + "," +
- formatter.FormatHexValue(arg2, 2);
+ string hash = gen.Quirks.BlockMoveArgsNoHash ? "" : "#";
+ formattedOperand = hash + formatter.FormatHexValue(arg1, 2) + "," +
+ hash + formatter.FormatHexValue(arg2, 2);
} else {
if (operandLen == 2) {
// This is necessary for 16-bit operands, like "LDA abs" and "PEA val",
diff --git a/SourceGen/AsmGen/IGenerator.cs b/SourceGen/AsmGen/IGenerator.cs
index eda5e5c..083f8b6 100644
--- a/SourceGen/AsmGen/IGenerator.cs
+++ b/SourceGen/AsmGen/IGenerator.cs
@@ -172,6 +172,11 @@ namespace SourceGen.AsmGen {
///
public bool BlockMoveArgsReversed { get; set; }
+ ///
+ /// Are 8-bit constant args to MVN/MVP output without a leading '#'?
+ ///
+ public bool BlockMoveArgsNoHash { get; set; }
+
///
/// Does the assembler configure assembler widths based on SEP/REP, but doesn't
/// track the emulation bit?
diff --git a/SourceGen/LineListGen.cs b/SourceGen/LineListGen.cs
index 5c4a043..5ef0084 100644
--- a/SourceGen/LineListGen.cs
+++ b/SourceGen/LineListGen.cs
@@ -1151,7 +1151,7 @@ namespace SourceGen {
string opstr2 = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable,
null, attr.DataDescriptor, operand & 0xff, 1,
PseudoOp.FormatNumericOpFlags.None);
- formattedOperand = opstr1 + "," + opstr2;
+ formattedOperand = '#' + opstr1 + "," + '#' + opstr2;
} else {
formattedOperand = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable,
null, attr.DataDescriptor, operandForSymbol, operandLen, opFlags);
@@ -1159,8 +1159,8 @@ namespace SourceGen {
} else {
// Show operand value in hex.
if (op.AddrMode == OpDef.AddressMode.BlockMove) {
- formattedOperand = formatter.FormatHexValue(operand >> 8, 2) + "," +
- formatter.FormatHexValue(operand & 0xff, 2);
+ formattedOperand = '#' + formatter.FormatHexValue(operand >> 8, 2) + "," +
+ '#' + formatter.FormatHexValue(operand & 0xff, 2);
} else {
if (operandLen == 2) {
// This is necessary for 16-bit operands, like "LDA abs" and "PEA val",
diff --git a/SourceGen/RuntimeData/Help/codegen.html b/SourceGen/RuntimeData/Help/codegen.html
index 33b6838..759fb58 100644
--- a/SourceGen/RuntimeData/Help/codegen.html
+++ b/SourceGen/RuntimeData/Help/codegen.html
@@ -192,6 +192,8 @@ code, but also needs to know how to handle the corner cases.
SourceGen for ACME also uses ".S".
Does not allow the accumulator to be specified explicitly as an
operand, e.g. you can't write LSR A
.
+ Syntax for MVN
/MVP
doesn't allow '#'
+ before 8-bit operands.
@@ -230,9 +232,6 @@ code, but also needs to know how to handle the corner cases.
multiple segments (it is, after all, an assembler for a C compiler).
A linker configuration script is expected to be provided for anything
complex. SourceGen generates a custom config file for each project.
- The syntax for the 65816 block move instructions
- (MVN
/MVP
) changed to a non-standard format
- in v2.18, requiring a '#' before 8-bit constants.
diff --git a/SourceGen/SGTestData/Expected/1000-allops-value-65816_64tass.S b/SourceGen/SGTestData/Expected/1000-allops-value-65816_64tass.S
index c46fc05..76f9739 100644
--- a/SourceGen/SGTestData/Expected/1000-allops-value-65816_64tass.S
+++ b/SourceGen/SGTestData/Expected/1000-allops-value-65816_64tass.S
@@ -87,7 +87,7 @@ L1089 and ($ff),y
L10AB eor ($ff,x)
.byte $42,$ff
eor $ff,s
- mvp $fe,$ff
+ mvp #$fe,#$ff
eor $ff
lsr $ff
eor [$ff]
@@ -104,7 +104,7 @@ L10C2 eor $feff
L10CE eor ($ff),y
eor ($ff)
eor ($ff,s),y
- mvn $fe,$ff
+ mvn #$fe,#$ff
eor $ff,x
lsr $ff,x
eor [$ff],y
diff --git a/SourceGen/SGTestData/Expected/1000-allops-value-65816_Merlin32.S b/SourceGen/SGTestData/Expected/1000-allops-value-65816_Merlin32.S
index 2506283..f85fd71 100644
--- a/SourceGen/SGTestData/Expected/1000-allops-value-65816_Merlin32.S
+++ b/SourceGen/SGTestData/Expected/1000-allops-value-65816_Merlin32.S
@@ -84,7 +84,7 @@ L1089 and ($ff),y
L10AB eor ($ff,x)
wdm $ff
eor $ff,S
- mvp $fe,$ff
+ mvp #$fe,#$ff
eor $ff
lsr $ff
eor [$ff]
@@ -101,7 +101,7 @@ L10C2 eor $feff
L10CE eor ($ff),y
eor ($ff)
eor ($ff,S),y
- mvn $fe,$ff
+ mvn #$fe,#$ff
eor $ff,x
lsr $ff,x
eor [$ff],y
diff --git a/SourceGen/SGTestData/Expected/1000-allops-value-65816_cc65.S b/SourceGen/SGTestData/Expected/1000-allops-value-65816_cc65.S
index cf4f432..7144762 100644
--- a/SourceGen/SGTestData/Expected/1000-allops-value-65816_cc65.S
+++ b/SourceGen/SGTestData/Expected/1000-allops-value-65816_cc65.S
@@ -88,7 +88,7 @@ L1089: and ($ff),y
L10AB: eor ($ff,x)
wdm $ff
eor $ff,S
- .byte $44,$ff,$fe
+ mvp #$fe,#$ff
eor $ff
lsr $ff
eor [$ff]
@@ -105,7 +105,7 @@ L10C2: eor $feff
L10CE: eor ($ff),y
eor ($ff)
eor ($ff,S),y
- .byte $54,$ff,$fe
+ mvn #$fe,#$ff
eor $ff,x
lsr $ff,x
eor [$ff],y
diff --git a/SourceGen/SGTestData/Expected/1001-allops-zero-65816_64tass.S b/SourceGen/SGTestData/Expected/1001-allops-zero-65816_64tass.S
index 305e6b2..9a4ec70 100644
--- a/SourceGen/SGTestData/Expected/1001-allops-zero-65816_64tass.S
+++ b/SourceGen/SGTestData/Expected/1001-allops-zero-65816_64tass.S
@@ -87,7 +87,7 @@ L1089 and ($00),y
L10AB eor ($00,x)
.byte $42,$00
eor $00,s
- mvp $00,$00
+ mvp #$00,#$00
eor $00
lsr $00
eor [$00]
@@ -104,7 +104,7 @@ L10C2 eor @w$0000
L10CE eor ($00),y
eor ($00)
eor ($00,s),y
- mvn $00,$00
+ mvn #$00,#$00
eor $00,x
lsr $00,x
eor [$00],y
diff --git a/SourceGen/SGTestData/Expected/1001-allops-zero-65816_Merlin32.S b/SourceGen/SGTestData/Expected/1001-allops-zero-65816_Merlin32.S
index 32d7e3c..12dea32 100644
--- a/SourceGen/SGTestData/Expected/1001-allops-zero-65816_Merlin32.S
+++ b/SourceGen/SGTestData/Expected/1001-allops-zero-65816_Merlin32.S
@@ -84,7 +84,7 @@ L1089 and ($00),y
L10AB eor ($00,x)
wdm $00
eor $00,S
- mvp $00,$00
+ mvp #$00,#$00
eor $00
lsr $00
eor [$00]
@@ -101,7 +101,7 @@ L10C2 eor: $0000
L10CE eor ($00),y
eor ($00)
eor ($00,S),y
- mvn $00,$00
+ mvn #$00,#$00
eor $00,x
lsr $00,x
eor [$00],y
diff --git a/SourceGen/SGTestData/Expected/1001-allops-zero-65816_cc65.S b/SourceGen/SGTestData/Expected/1001-allops-zero-65816_cc65.S
index 67a4877..364ea29 100644
--- a/SourceGen/SGTestData/Expected/1001-allops-zero-65816_cc65.S
+++ b/SourceGen/SGTestData/Expected/1001-allops-zero-65816_cc65.S
@@ -88,7 +88,7 @@ L1089: and ($00),y
L10AB: eor ($00,x)
wdm $00
eor $00,S
- .byte $44,$00,$00
+ mvp #$00,#$00
eor $00
lsr $00
eor [$00]
@@ -105,7 +105,7 @@ L10C2: eor a:$0000
L10CE: eor ($00),y
eor ($00)
eor ($00,S),y
- .byte $54,$00,$00
+ mvn #$00,#$00
eor $00,x
lsr $00,x
eor [$00],y
diff --git a/SourceGen/SGTestData/Expected/2007-labels-and-symbols_64tass.S b/SourceGen/SGTestData/Expected/2007-labels-and-symbols_64tass.S
index 7ef5e72..fbddda3 100644
--- a/SourceGen/SGTestData/Expected/2007-labels-and-symbols_64tass.S
+++ b/SourceGen/SGTestData/Expected/2007-labels-and-symbols_64tass.S
@@ -114,10 +114,10 @@ start clc
.dword 0+(start >> 16)
skipdata lda #(biggie >> 16)-1
- mvn `biggie,(`biggie)-17
- mvp `start,(`start)+17
- mvn 18,1
- mvp %00000001,%00010010
+ mvn #`biggie,#(`biggie)-17
+ mvp #`start,#(`start)+17
+ mvn #18,#1
+ mvp #%00000001,#%00010010
per skipdata
brl nextchunk
diff --git a/SourceGen/SGTestData/Expected/2007-labels-and-symbols_Merlin32.S b/SourceGen/SGTestData/Expected/2007-labels-and-symbols_Merlin32.S
index c58c772..6fd6d4d 100644
--- a/SourceGen/SGTestData/Expected/2007-labels-and-symbols_Merlin32.S
+++ b/SourceGen/SGTestData/Expected/2007-labels-and-symbols_Merlin32.S
@@ -110,10 +110,10 @@ start clc
adrl ^start
skipdata lda #^biggie-65536
- mvn ^biggie,^biggie-1114112
- mvp ^start,^start+1114112
- mvn 18,1
- mvp %00000001,%00010010
+ mvn #^biggie,#^biggie-1114112
+ mvp #^start,#^start+1114112
+ mvn #18,#1
+ mvp #%00000001,#%00010010
per skipdata
brl nextchunk
diff --git a/SourceGen/SGTestData/Expected/2007-labels-and-symbols_cc65.S b/SourceGen/SGTestData/Expected/2007-labels-and-symbols_cc65.S
index 716690a..5644b82 100644
--- a/SourceGen/SGTestData/Expected/2007-labels-and-symbols_cc65.S
+++ b/SourceGen/SGTestData/Expected/2007-labels-and-symbols_cc65.S
@@ -115,10 +115,10 @@ start: clc
.dword start >> 16
skipdata: lda #biggie >> 16 -1
- .byte $54,$01,$12
- .byte $44,$12,$01
- .byte $54,$01,$12
- .byte $44,$12,$01
+ mvn #^biggie,#^biggie-17
+ mvp #^start,#^start+17
+ mvn #18,#1
+ mvp #%00000001,#%00010010
per skipdata
brl nextchunk
diff --git a/SourceGen/SGTestData/Expected/2014-label-dp_64tass.S b/SourceGen/SGTestData/Expected/2014-label-dp_64tass.S
index f30a278..cfdd41b 100644
--- a/SourceGen/SGTestData/Expected/2014-label-dp_64tass.S
+++ b/SourceGen/SGTestData/Expected/2014-label-dp_64tass.S
@@ -88,7 +88,7 @@ L1089 and (L0080),y
L10AB eor (L0080,x)
.byte $42,$80
eor $80,s
- mvp $84,$83
+ mvp #$84,#$83
eor L0080
lsr L0080
eor [L0080]
@@ -105,7 +105,7 @@ L10C2 eor @wL0086
L10CE eor (L0080),y
eor (L0080)
eor ($80,s),y
- mvn $84,$83
+ mvn #$84,#$83
eor L0080,x
lsr L0080,x
eor [L0080],y
diff --git a/SourceGen/SGTestData/Expected/2014-label-dp_Merlin32.S b/SourceGen/SGTestData/Expected/2014-label-dp_Merlin32.S
index 0dadda8..bde743f 100644
--- a/SourceGen/SGTestData/Expected/2014-label-dp_Merlin32.S
+++ b/SourceGen/SGTestData/Expected/2014-label-dp_Merlin32.S
@@ -85,7 +85,7 @@ L1089 and (L0080),y
L10AB dfb $41,$80
wdm $80
eor $80,S
- mvp $84,$83
+ mvp #$84,#$83
eor L0080
lsr L0080
dfb $47,$80
@@ -102,7 +102,7 @@ L10C2 eor: L0086
L10CE eor (L0080),y
dfb $52,$80
eor ($80,S),y
- mvn $84,$83
+ mvn #$84,#$83
eor L0080,x
lsr L0080,x
eor [L0080],y
diff --git a/SourceGen/SGTestData/Expected/2014-label-dp_cc65.S b/SourceGen/SGTestData/Expected/2014-label-dp_cc65.S
index 0e81fb3..c95b844 100644
--- a/SourceGen/SGTestData/Expected/2014-label-dp_cc65.S
+++ b/SourceGen/SGTestData/Expected/2014-label-dp_cc65.S
@@ -89,7 +89,7 @@ L1089: and (L0080),y
L10AB: eor (L0080,x)
wdm $80
eor $80,S
- .byte $44,$83,$84
+ mvp #$84,#$83
eor z:L0080
lsr z:L0080
eor [L0080]
@@ -106,7 +106,7 @@ L10C2: eor a:L0086
L10CE: eor (L0080),y
eor (L0080)
eor ($80,S),y
- .byte $54,$83,$84
+ mvn #$84,#$83
eor z:L0080,x
lsr z:L0080,x
eor [L0080],y