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