diff --git a/Asm65/StringOpFormatter.cs b/Asm65/StringOpFormatter.cs index b6a2bd3..6be70f8 100644 --- a/Asm65/StringOpFormatter.cs +++ b/Asm65/StringOpFormatter.cs @@ -31,8 +31,17 @@ namespace Asm65 { /// public enum ReverseMode { Forward, LineReverse, FullReverse }; + /// + /// Character encoding conversion delegate. This function converts a raw byte value + /// to a printable value, or CharEncoding.UNPRINTABLE_CHAR. + /// public CharEncoding.Convert CharConv { get; set; } + /// + /// True if the input bytes are a DCI string. Only compatible with ReverseMode==Forward. + /// + public bool IsDciString { get; set; } = false; + // Output format for raw (non-printable) characters. Most assemblers use comma-separated // hex values, some allow dense hex strings. public enum RawOutputStyle { DenseHex, CommaSep }; @@ -252,6 +261,8 @@ namespace Asm65 { /// public void FeedBytes(byte[] data, int offset, int length, int leadingBytes, ReverseMode revMode) { + Debug.Assert(!IsDciString || revMode == ReverseMode.Forward); + int startOffset = offset; int strEndOffset = offset + length; @@ -288,7 +299,11 @@ namespace Asm65 { } else { Debug.Assert(revMode == ReverseMode.Forward); for (; offset < strEndOffset; offset++) { - WriteChar(data[offset]); + byte val = data[offset]; + if (IsDciString && offset == strEndOffset - 1) { + val ^= 0x80; + } + WriteChar(val); } } diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs index 70393a2..b2f3546 100644 --- a/SourceGen/AsmGen/AsmMerlin32.cs +++ b/SourceGen/AsmGen/AsmMerlin32.cs @@ -626,12 +626,7 @@ namespace SourceGen.AsmGen { StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, new Formatter.DelimiterDef(delim), StringOpFormatter.RawOutputStyle.DenseHex, charConv, false); - if (dfd.FormatType == FormatDescriptor.Type.StringDci) { - // DCI is awkward because the character encoding flips on the last byte. Rather - // than clutter up StringOpFormatter for this rare item, we just accept low/high - // throughout. - stropf.CharConv = CharEncoding.ConvertLowAndHighAscii; - } + stropf.IsDciString = (dfd.FormatType == FormatDescriptor.Type.StringDci); // Feed bytes in, skipping over the leading length bytes. stropf.FeedBytes(data, offset + leadingBytes, @@ -672,7 +667,7 @@ namespace SourceGen.AsmGen { if (stropf.Lines.Count != 1) { // single-line only opcodeStr = sDataOpNames.StrGeneric; - stropf.CharConv = charConv; + stropf.IsDciString = false; redo = true; } break; diff --git a/SourceGen/AsmGen/AsmTass64.cs b/SourceGen/AsmGen/AsmTass64.cs index bf4921b..5fcb6ba 100644 --- a/SourceGen/AsmGen/AsmTass64.cs +++ b/SourceGen/AsmGen/AsmTass64.cs @@ -750,23 +750,18 @@ namespace SourceGen.AsmGen { Debug.Assert(dfd.Length > 0); CharEncoding.Convert charConv = null; - CharEncoding.Convert dciConv = null; switch (dfd.FormatSubType) { case FormatDescriptor.SubType.Ascii: charConv = CharEncoding.ConvertAscii; - dciConv = CharEncoding.ConvertLowAndHighAscii; break; case FormatDescriptor.SubType.HighAscii: charConv = CharEncoding.ConvertHighAscii; - dciConv = CharEncoding.ConvertLowAndHighAscii; break; case FormatDescriptor.SubType.C64Petscii: charConv = CharEncoding.ConvertC64Petscii; - dciConv = CharEncoding.ConvertLowAndHighC64Petscii; break; case FormatDescriptor.SubType.C64Screen: charConv = CharEncoding.ConvertC64ScreenCode; - dciConv = CharEncoding.ConvertLowAndHighC64ScreenCode; break; default: break; @@ -808,6 +803,7 @@ namespace SourceGen.AsmGen { if ((Project.FileData[offset + dfd.Length - 1] & 0x80) == 0) { // ".shift" directive only works for strings where the low bit starts // clear and ends high. + // TODO(maybe): this is sub-optimal for high-ASCII DCI strings. OutputNoJoy(offset, dfd.Length, labelStr, commentStr); return; } @@ -820,12 +816,7 @@ namespace SourceGen.AsmGen { StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, charConv, false); - if (dfd.FormatType == FormatDescriptor.Type.StringDci) { - // DCI is awkward because the character encoding flips on the last byte. Rather - // than clutter up StringOpFormatter for this rare item, we just accept low/high - // throughout. - stropf.CharConv = dciConv; - } + stropf.IsDciString = (dfd.FormatType == FormatDescriptor.Type.StringDci); // Feed bytes in, skipping over hidden bytes (leading L8, trailing null). stropf.FeedBytes(data, offset + hiddenLeadingBytes, @@ -847,7 +838,7 @@ namespace SourceGen.AsmGen { if (stropf.Lines.Count != 1) { // Must be single-line. opcodeStr = sDataOpNames.StrGeneric; - stropf.CharConv = charConv; // undo DCI hack + stropf.IsDciString = false; redo = true; } break; diff --git a/SourceGen/PseudoOp.cs b/SourceGen/PseudoOp.cs index 8ba882a..13c4fbb 100644 --- a/SourceGen/PseudoOp.cs +++ b/SourceGen/PseudoOp.cs @@ -442,13 +442,11 @@ namespace SourceGen { /// Format descriptor. /// File data. /// Offset, within data, of start of string. - /// Pseudo-opcode string. + /// Receives the pseudo-opcode string. /// Array of operand strings. public static List FormatStringOp(Formatter formatter, PseudoOpNames opNames, FormatDescriptor dfd, byte[] data, int offset, out string popcode) { - int hiddenLeadingBytes = 0; - int trailingBytes = 0; StringOpFormatter.ReverseMode revMode = StringOpFormatter.ReverseMode.Forward; Formatter.DelimiterSet delSet = formatter.Config.mStringDelimiters; Formatter.DelimiterDef delDef; @@ -456,35 +454,19 @@ namespace SourceGen { CharEncoding.Convert charConv; switch (dfd.FormatSubType) { case FormatDescriptor.SubType.Ascii: - if (dfd.FormatType == FormatDescriptor.Type.StringDci) { - charConv = CharEncoding.ConvertLowAndHighAscii; - } else { - charConv = CharEncoding.ConvertAscii; - } + charConv = CharEncoding.ConvertAscii; delDef = delSet.Get(CharEncoding.Encoding.Ascii); break; case FormatDescriptor.SubType.HighAscii: - if (dfd.FormatType == FormatDescriptor.Type.StringDci) { - charConv = CharEncoding.ConvertLowAndHighAscii; - } else { - charConv = CharEncoding.ConvertHighAscii; - } + charConv = CharEncoding.ConvertHighAscii; delDef = delSet.Get(CharEncoding.Encoding.HighAscii); break; case FormatDescriptor.SubType.C64Petscii: - if (dfd.FormatType == FormatDescriptor.Type.StringDci) { - charConv = CharEncoding.ConvertLowAndHighC64Petscii; - } else { - charConv = CharEncoding.ConvertC64Petscii; - } + charConv = CharEncoding.ConvertC64Petscii; delDef = delSet.Get(CharEncoding.Encoding.C64Petscii); break; case FormatDescriptor.SubType.C64Screen: - if (dfd.FormatType == FormatDescriptor.Type.StringDci) { - charConv = CharEncoding.ConvertLowAndHighC64ScreenCode; - } else { - charConv = CharEncoding.ConvertC64ScreenCode; - } + charConv = CharEncoding.ConvertC64ScreenCode; delDef = delSet.Get(CharEncoding.Encoding.C64ScreenCode); break; default: @@ -498,6 +480,11 @@ namespace SourceGen { delDef = Formatter.DOUBLE_QUOTE_DELIM; } + StringOpFormatter stropf = new StringOpFormatter(formatter, delDef, + StringOpFormatter.RawOutputStyle.CommaSep, charConv, false); + + int hiddenLeadingBytes = 0; + int trailingBytes = 0; switch (dfd.FormatType) { case FormatDescriptor.Type.StringGeneric: // Generic character data. @@ -513,30 +500,22 @@ namespace SourceGen { // Character data with a terminating null. Don't show the null byte. popcode = opNames.StrNullTerm; trailingBytes = 1; - //if (strLen == 0) { - // showHexZeroes = 1; - //} break; case FormatDescriptor.Type.StringL8: // Character data with a leading length byte. Don't show the length. hiddenLeadingBytes = 1; - //if (strLen == 0) { - // showHexZeroes = 1; - //} popcode = opNames.StrLen8; break; case FormatDescriptor.Type.StringL16: // Character data with a leading length word. Don't show the length. Debug.Assert(dfd.Length > 1); hiddenLeadingBytes = 2; - //if (strLen == 0) { - // showHexZeroes = 2; - //} popcode = opNames.StrLen16; break; case FormatDescriptor.Type.StringDci: // High bit on last byte is flipped. popcode = opNames.StrDci; + stropf.IsDciString = true; break; default: Debug.Assert(false); @@ -544,8 +523,6 @@ namespace SourceGen { break; } - StringOpFormatter stropf = new StringOpFormatter(formatter, delDef, - StringOpFormatter.RawOutputStyle.CommaSep, charConv, false); stropf.FeedBytes(data, offset + hiddenLeadingBytes, dfd.Length - hiddenLeadingBytes - trailingBytes, 0, revMode); diff --git a/SourceGen/SGTestData/20120-char-encoding-a b/SourceGen/SGTestData/20120-char-encoding-a index eaac713..a0953cb 100644 Binary files a/SourceGen/SGTestData/20120-char-encoding-a and b/SourceGen/SGTestData/20120-char-encoding-a differ diff --git a/SourceGen/SGTestData/20120-char-encoding-a.dis65 b/SourceGen/SGTestData/20120-char-encoding-a.dis65 index 662918d..0da3604 100644 --- a/SourceGen/SGTestData/20120-char-encoding-a.dis65 +++ b/SourceGen/SGTestData/20120-char-encoding-a.dis65 @@ -1,8 +1,8 @@ ### 6502bench SourceGen dis65 v1.0 ### { "_ContentVersion":4, -"FileDataLength":1299, -"FileDataCrc32":-371479809, +"FileDataLength":1417, +"FileDataCrc32":212868891, "ProjectProps":{ "CpuName":"6502", "IncludeUndocumentedInstr":false, @@ -786,6 +786,84 @@ "Length":1, "Format":"StringDci", "SubFormat":"C64Screen", +"SymbolRef":null}, + +"1297":{ +"Length":6, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1304":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1314":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1325":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"HighAscii", +"SymbolRef":null}, + +"1336":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"HighAscii", +"SymbolRef":null}, + +"1348":{ +"Length":8, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1357":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1367":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1378":{ +"Length":1, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1380":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1392":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1402":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1413":{ +"Length":1, +"Format":"StringDci", +"SubFormat":"C64Screen", "SymbolRef":null}}, "LvTables":{ diff --git a/SourceGen/SGTestData/20130-char-encoding-p b/SourceGen/SGTestData/20130-char-encoding-p index eaac713..a0953cb 100644 Binary files a/SourceGen/SGTestData/20130-char-encoding-p and b/SourceGen/SGTestData/20130-char-encoding-p differ diff --git a/SourceGen/SGTestData/20130-char-encoding-p.dis65 b/SourceGen/SGTestData/20130-char-encoding-p.dis65 index 7c95071..cf67988 100644 --- a/SourceGen/SGTestData/20130-char-encoding-p.dis65 +++ b/SourceGen/SGTestData/20130-char-encoding-p.dis65 @@ -1,8 +1,8 @@ ### 6502bench SourceGen dis65 v1.0 ### { "_ContentVersion":4, -"FileDataLength":1299, -"FileDataCrc32":-371479809, +"FileDataLength":1417, +"FileDataCrc32":212868891, "ProjectProps":{ "CpuName":"6502", "IncludeUndocumentedInstr":false, @@ -786,6 +786,84 @@ "Length":1, "Format":"StringDci", "SubFormat":"C64Screen", +"SymbolRef":null}, + +"1297":{ +"Length":6, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1304":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1314":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1325":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"HighAscii", +"SymbolRef":null}, + +"1336":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"HighAscii", +"SymbolRef":null}, + +"1348":{ +"Length":8, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1357":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1367":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1378":{ +"Length":1, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1380":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1392":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1402":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1413":{ +"Length":1, +"Format":"StringDci", +"SubFormat":"C64Screen", "SymbolRef":null}}, "LvTables":{ diff --git a/SourceGen/SGTestData/20140-char-encoding-s b/SourceGen/SGTestData/20140-char-encoding-s index eaac713..a0953cb 100644 Binary files a/SourceGen/SGTestData/20140-char-encoding-s and b/SourceGen/SGTestData/20140-char-encoding-s differ diff --git a/SourceGen/SGTestData/20140-char-encoding-s.dis65 b/SourceGen/SGTestData/20140-char-encoding-s.dis65 index 7b9099b..c18980b 100644 --- a/SourceGen/SGTestData/20140-char-encoding-s.dis65 +++ b/SourceGen/SGTestData/20140-char-encoding-s.dis65 @@ -1,8 +1,8 @@ ### 6502bench SourceGen dis65 v1.0 ### { "_ContentVersion":4, -"FileDataLength":1299, -"FileDataCrc32":-371479809, +"FileDataLength":1417, +"FileDataCrc32":212868891, "ProjectProps":{ "CpuName":"6502", "IncludeUndocumentedInstr":false, @@ -786,6 +786,84 @@ "Length":1, "Format":"StringDci", "SubFormat":"C64Screen", +"SymbolRef":null}, + +"1297":{ +"Length":6, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1304":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1314":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"Ascii", +"SymbolRef":null}, + +"1325":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"HighAscii", +"SymbolRef":null}, + +"1336":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"HighAscii", +"SymbolRef":null}, + +"1348":{ +"Length":8, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1357":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1367":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1378":{ +"Length":1, +"Format":"StringDci", +"SubFormat":"C64Petscii", +"SymbolRef":null}, + +"1380":{ +"Length":11, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1392":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1402":{ +"Length":10, +"Format":"StringDci", +"SubFormat":"C64Screen", +"SymbolRef":null}, + +"1413":{ +"Length":1, +"Format":"StringDci", +"SubFormat":"C64Screen", "SymbolRef":null}}, "LvTables":{ diff --git a/SourceGen/SGTestData/Expected/20120-char-encoding-a_64tass.S b/SourceGen/SGTestData/Expected/20120-char-encoding-a_64tass.S index 470fda0..93ca00e 100644 --- a/SourceGen/SGTestData/Expected/20120-char-encoding-a_64tass.S +++ b/SourceGen/SGTestData/Expected/20120-char-encoding-a_64tass.S @@ -251,7 +251,7 @@ L144B nop .byte $80 _L14DA nop - jmp _L1511 + jmp _L1587 .byte $86 .enc "sg_ascii" @@ -284,7 +284,33 @@ _L14DA nop .shift "X" .shift "!" .byte $86 + .enc "sg_ascii" + .shift "ascii",$7f + .byte $86 + .shift $22,"A quote1",$22 + .shift "'A quote2'" + .byte $86 + .enc "sg_hiascii" + .byte $a2,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b1,$22 + .byte $a7,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b2,$27 + .byte $86 + .enc "none" + .shift "petscii",$5e + .byte $86 + .shift $22,"a quote1",$22 + .shift "'a quote2'" + .byte $86 + .shift $5c + .byte $86 + .enc "screen" + .shift "ScreenCode",$1e + .byte $86 + .shift $22,"A quote1",$22 + .shift "'A quote2'" + .byte $86 + .shift $1c + .byte $86 -_L1511 nop +_L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20120-char-encoding-a_acme.S b/SourceGen/SGTestData/Expected/20120-char-encoding-a_acme.S index 41d21a7..1980c8d 100644 --- a/SourceGen/SGTestData/Expected/20120-char-encoding-a_acme.S +++ b/SourceGen/SGTestData/Expected/20120-char-encoding-a_acme.S @@ -220,7 +220,7 @@ L144B nop !byte $80 @L14DA nop - jmp @L1511 + jmp @L1587 !byte $86 !text "Hell",$ef @@ -248,7 +248,29 @@ L144B nop !scr $d8 !scr $a1 !byte $86 + !text "ascii",$ff + !byte $86 + !text $22,"A quote1",$a2 + !text "'A quote2",$a7 + !byte $86 + !hex a2c8c1a0f1f5eff4e5b122 + !hex a7c8c1a0f1f5eff4e5b227 + !byte $86 + !pet "petscii",$de + !byte $86 + !pet $22,"a quote1",$a2 + !pet "'a quote2",$a7 + !byte $86 + !pet $dc + !byte $86 + !scr "ScreenCode",$9e + !byte $86 + !scr $22,"A quote1",$a2 + !scr "'A quote2",$a7 + !byte $86 + !scr $9c + !byte $86 -@L1511 nop +@L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.S b/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.S index 7503a0e..ded807f 100644 --- a/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.S +++ b/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.S @@ -247,7 +247,7 @@ L144B: nop .byte $80 @L14DA: nop - jmp @L1511 + jmp @L1587 .byte $86 .byte "Hell",$ef @@ -275,7 +275,29 @@ L144B: nop .byte $d8 .byte $a1 .byte $86 + .byte "ascii",$ff + .byte $86 + .byte $22,"A quote1",$a2 + .byte "'A quote2",$a7 + .byte $86 + .byte $a2,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b1,$22 + .byte $a7,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b2,$27 + .byte $86 + .byte $50,$45,$54,$53,$43,$49,$49,$de + .byte $86 + .byte $22,$41,$20,$51,$55,$4f,$54,$45,$31,$a2 + .byte $27,$41,$20,$51,$55,$4f,$54,$45,$32,$a7 + .byte $86 + .byte $dc + .byte $86 + .byte $53,$03,$12,$05,$05,$0e,$43,$0f,$04,$05,$9e + .byte $86 + .byte $22,$41,$20,$11,$15,$0f,$14,$05,$31,$a2 + .byte $27,$41,$20,$11,$15,$0f,$14,$05,$32,$a7 + .byte $86 + .byte $9c + .byte $86 -@L1511: nop +@L1587: nop rts diff --git a/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.cfg b/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.cfg index bbb91e4..5f4cb6f 100644 --- a/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.cfg +++ b/SourceGen/SGTestData/Expected/20120-char-encoding-a_cc65.cfg @@ -1,7 +1,7 @@ # 6502bench SourceGen generated linker script for 20120-char-encoding-a MEMORY { MAIN: file=%O, start=%S, size=65536; -# MEM000: file=%O, start=$1000, size=1299; +# MEM000: file=%O, start=$1000, size=1417; } SEGMENTS { CODE: load=MAIN, type=rw; diff --git a/SourceGen/SGTestData/Expected/20120-char-encoding-a_merlin32.S b/SourceGen/SGTestData/Expected/20120-char-encoding-a_merlin32.S index 50b0d1f..f882640 100644 --- a/SourceGen/SGTestData/Expected/20120-char-encoding-a_merlin32.S +++ b/SourceGen/SGTestData/Expected/20120-char-encoding-a_merlin32.S @@ -214,7 +214,7 @@ L144B nop dfb $80 :L14DA nop - jmp :L1511 + jmp :L1587 dfb $86 dci 'Hello' @@ -242,7 +242,29 @@ L144B nop hex d8 hex a1 dfb $86 + dci 'ascii',7f + dfb $86 + dci '"A quote1"' + dci 27,'A quote2',27 + dfb $86 + dci a2,"HA quote1",a2 + dci "'HA quote2'" + dfb $86 + hex 50455453434949de + dfb $86 + hex 22412051554f544531a2 + hex 27412051554f544532a7 + dfb $86 + hex dc + dfb $86 + hex 53031205050e430f04059e + dfb $86 + hex 22412011150f140531a2 + hex 27412011150f140532a7 + dfb $86 + hex 9c + dfb $86 -:L1511 nop +:L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20130-char-encoding-p_64tass.S b/SourceGen/SGTestData/Expected/20130-char-encoding-p_64tass.S index a143597..76c8773 100644 --- a/SourceGen/SGTestData/Expected/20130-char-encoding-p_64tass.S +++ b/SourceGen/SGTestData/Expected/20130-char-encoding-p_64tass.S @@ -344,7 +344,7 @@ L144B nop .byte $80 _L14DA nop - jmp _L1511 + jmp _L1587 .byte $86 .enc "sg_ascii" @@ -377,7 +377,33 @@ _L14DA nop .shift "X" .shift "!" .byte $86 + .enc "sg_ascii" + .shift "ascii",$7f + .byte $86 + .shift $22,"A quote1",$22 + .shift "'A quote2'" + .byte $86 + .enc "sg_hiascii" + .byte $a2,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b1,$22 + .byte $a7,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b2,$27 + .byte $86 + .enc "none" + .shift "petscii",$5e + .byte $86 + .shift $22,"a quote1",$22 + .shift "'a quote2'" + .byte $86 + .shift $5c + .byte $86 + .enc "screen" + .shift "ScreenCode",$1e + .byte $86 + .shift $22,"A quote1",$22 + .shift "'A quote2'" + .byte $86 + .shift $1c + .byte $86 -_L1511 nop +_L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20130-char-encoding-p_acme.S b/SourceGen/SGTestData/Expected/20130-char-encoding-p_acme.S index ceecb1b..a2b005f 100644 --- a/SourceGen/SGTestData/Expected/20130-char-encoding-p_acme.S +++ b/SourceGen/SGTestData/Expected/20130-char-encoding-p_acme.S @@ -313,7 +313,7 @@ L144B nop !byte $80 @L14DA nop - jmp @L1511 + jmp @L1587 !byte $86 !text "Hell",$ef @@ -341,7 +341,29 @@ L144B nop !scr $d8 !scr $a1 !byte $86 + !text "ascii",$ff + !byte $86 + !text $22,"A quote1",$a2 + !text "'A quote2",$a7 + !byte $86 + !hex a2c8c1a0f1f5eff4e5b122 + !hex a7c8c1a0f1f5eff4e5b227 + !byte $86 + !pet "petscii",$de + !byte $86 + !pet $22,"a quote1",$a2 + !pet "'a quote2",$a7 + !byte $86 + !pet $dc + !byte $86 + !scr "ScreenCode",$9e + !byte $86 + !scr $22,"A quote1",$a2 + !scr "'A quote2",$a7 + !byte $86 + !scr $9c + !byte $86 -@L1511 nop +@L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.S b/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.S index 29d3bc5..60e8bba 100644 --- a/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.S +++ b/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.S @@ -340,7 +340,7 @@ L144B: nop .byte $80 @L14DA: nop - jmp @L1511 + jmp @L1587 .byte $86 .byte "Hell",$ef @@ -368,7 +368,29 @@ L144B: nop .byte $d8 .byte $a1 .byte $86 + .byte "ascii",$ff + .byte $86 + .byte $22,"A quote1",$a2 + .byte "'A quote2",$a7 + .byte $86 + .byte $a2,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b1,$22 + .byte $a7,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b2,$27 + .byte $86 + .byte $50,$45,$54,$53,$43,$49,$49,$de + .byte $86 + .byte $22,$41,$20,$51,$55,$4f,$54,$45,$31,$a2 + .byte $27,$41,$20,$51,$55,$4f,$54,$45,$32,$a7 + .byte $86 + .byte $dc + .byte $86 + .byte $53,$03,$12,$05,$05,$0e,$43,$0f,$04,$05,$9e + .byte $86 + .byte $22,$41,$20,$11,$15,$0f,$14,$05,$31,$a2 + .byte $27,$41,$20,$11,$15,$0f,$14,$05,$32,$a7 + .byte $86 + .byte $9c + .byte $86 -@L1511: nop +@L1587: nop rts diff --git a/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.cfg b/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.cfg index e8dbd15..dfbe7bb 100644 --- a/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.cfg +++ b/SourceGen/SGTestData/Expected/20130-char-encoding-p_cc65.cfg @@ -1,7 +1,7 @@ # 6502bench SourceGen generated linker script for 20130-char-encoding-p MEMORY { MAIN: file=%O, start=%S, size=65536; -# MEM000: file=%O, start=$1000, size=1299; +# MEM000: file=%O, start=$1000, size=1417; } SEGMENTS { CODE: load=MAIN, type=rw; diff --git a/SourceGen/SGTestData/Expected/20130-char-encoding-p_merlin32.S b/SourceGen/SGTestData/Expected/20130-char-encoding-p_merlin32.S index 3fdcc90..1dab7c5 100644 --- a/SourceGen/SGTestData/Expected/20130-char-encoding-p_merlin32.S +++ b/SourceGen/SGTestData/Expected/20130-char-encoding-p_merlin32.S @@ -308,7 +308,7 @@ L144B nop dfb $80 :L14DA nop - jmp :L1511 + jmp :L1587 dfb $86 dci 'Hello' @@ -336,7 +336,29 @@ L144B nop hex d8 hex a1 dfb $86 + dci 'ascii',7f + dfb $86 + dci '"A quote1"' + dci 27,'A quote2',27 + dfb $86 + dci a2,"HA quote1",a2 + dci "'HA quote2'" + dfb $86 + hex 50455453434949de + dfb $86 + hex 22412051554f544531a2 + hex 27412051554f544532a7 + dfb $86 + hex dc + dfb $86 + hex 53031205050e430f04059e + dfb $86 + hex 22412011150f140531a2 + hex 27412011150f140532a7 + dfb $86 + hex 9c + dfb $86 -:L1511 nop +:L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20140-char-encoding-s_64tass.S b/SourceGen/SGTestData/Expected/20140-char-encoding-s_64tass.S index 2bede8c..4d3cf5f 100644 --- a/SourceGen/SGTestData/Expected/20140-char-encoding-s_64tass.S +++ b/SourceGen/SGTestData/Expected/20140-char-encoding-s_64tass.S @@ -352,7 +352,7 @@ L144B nop .byte $80 _L14DA nop - jmp _L1511 + jmp _L1587 .byte $86 .enc "sg_ascii" @@ -385,7 +385,33 @@ _L14DA nop .shift "X" .shift "!" .byte $86 + .enc "sg_ascii" + .shift "ascii",$7f + .byte $86 + .shift $22,"A quote1",$22 + .shift "'A quote2'" + .byte $86 + .enc "sg_hiascii" + .byte $a2,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b1,$22 + .byte $a7,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b2,$27 + .byte $86 + .enc "none" + .shift "petscii",$5e + .byte $86 + .shift $22,"a quote1",$22 + .shift "'a quote2'" + .byte $86 + .shift $5c + .byte $86 + .enc "screen" + .shift "ScreenCode",$1e + .byte $86 + .shift $22,"A quote1",$22 + .shift "'A quote2'" + .byte $86 + .shift $1c + .byte $86 -_L1511 nop +_L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20140-char-encoding-s_acme.S b/SourceGen/SGTestData/Expected/20140-char-encoding-s_acme.S index d2774ac..ebb2204 100644 --- a/SourceGen/SGTestData/Expected/20140-char-encoding-s_acme.S +++ b/SourceGen/SGTestData/Expected/20140-char-encoding-s_acme.S @@ -322,7 +322,7 @@ L144B nop !byte $80 @L14DA nop - jmp @L1511 + jmp @L1587 !byte $86 !text "Hell",$ef @@ -350,7 +350,29 @@ L144B nop !scr $d8 !scr $a1 !byte $86 + !text "ascii",$ff + !byte $86 + !text $22,"A quote1",$a2 + !text "'A quote2",$a7 + !byte $86 + !hex a2c8c1a0f1f5eff4e5b122 + !hex a7c8c1a0f1f5eff4e5b227 + !byte $86 + !pet "petscii",$de + !byte $86 + !pet $22,"a quote1",$a2 + !pet "'a quote2",$a7 + !byte $86 + !pet $dc + !byte $86 + !scr "ScreenCode",$9e + !byte $86 + !scr $22,"A quote1",$a2 + !scr "'A quote2",$a7 + !byte $86 + !scr $9c + !byte $86 -@L1511 nop +@L1587 nop rts diff --git a/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.S b/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.S index 8ea10bd..18e5686 100644 --- a/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.S +++ b/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.S @@ -349,7 +349,7 @@ L144B: nop .byte $80 @L14DA: nop - jmp @L1511 + jmp @L1587 .byte $86 .byte "Hell",$ef @@ -377,7 +377,29 @@ L144B: nop .byte $d8 .byte $a1 .byte $86 + .byte "ascii",$ff + .byte $86 + .byte $22,"A quote1",$a2 + .byte "'A quote2",$a7 + .byte $86 + .byte $a2,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b1,$22 + .byte $a7,$c8,$c1,$a0,$f1,$f5,$ef,$f4,$e5,$b2,$27 + .byte $86 + .byte $50,$45,$54,$53,$43,$49,$49,$de + .byte $86 + .byte $22,$41,$20,$51,$55,$4f,$54,$45,$31,$a2 + .byte $27,$41,$20,$51,$55,$4f,$54,$45,$32,$a7 + .byte $86 + .byte $dc + .byte $86 + .byte $53,$03,$12,$05,$05,$0e,$43,$0f,$04,$05,$9e + .byte $86 + .byte $22,$41,$20,$11,$15,$0f,$14,$05,$31,$a2 + .byte $27,$41,$20,$11,$15,$0f,$14,$05,$32,$a7 + .byte $86 + .byte $9c + .byte $86 -@L1511: nop +@L1587: nop rts diff --git a/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.cfg b/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.cfg index 7e3b9d0..e3e6e84 100644 --- a/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.cfg +++ b/SourceGen/SGTestData/Expected/20140-char-encoding-s_cc65.cfg @@ -1,7 +1,7 @@ # 6502bench SourceGen generated linker script for 20140-char-encoding-s MEMORY { MAIN: file=%O, start=%S, size=65536; -# MEM000: file=%O, start=$1000, size=1299; +# MEM000: file=%O, start=$1000, size=1417; } SEGMENTS { CODE: load=MAIN, type=rw; diff --git a/SourceGen/SGTestData/Expected/20140-char-encoding-s_merlin32.S b/SourceGen/SGTestData/Expected/20140-char-encoding-s_merlin32.S index 3b93e5e..a8232a6 100644 --- a/SourceGen/SGTestData/Expected/20140-char-encoding-s_merlin32.S +++ b/SourceGen/SGTestData/Expected/20140-char-encoding-s_merlin32.S @@ -317,7 +317,7 @@ L144B nop dfb $80 :L14DA nop - jmp :L1511 + jmp :L1587 dfb $86 dci 'Hello' @@ -345,7 +345,29 @@ L144B nop hex d8 hex a1 dfb $86 + dci 'ascii',7f + dfb $86 + dci '"A quote1"' + dci 27,'A quote2',27 + dfb $86 + dci a2,"HA quote1",a2 + dci "'HA quote2'" + dfb $86 + hex 50455453434949de + dfb $86 + hex 22412051554f544531a2 + hex 27412051554f544532a7 + dfb $86 + hex dc + dfb $86 + hex 53031205050e430f04059e + dfb $86 + hex 22412011150f140531a2 + hex 27412011150f140532a7 + dfb $86 + hex 9c + dfb $86 -:L1511 nop +:L1587 nop rts diff --git a/SourceGen/SGTestData/Source/20010-string-types.S b/SourceGen/SGTestData/Source/20010-string-types.S index e88fd06..1cb7120 100644 --- a/SourceGen/SGTestData/Source/20010-string-types.S +++ b/SourceGen/SGTestData/Source/20010-string-types.S @@ -45,13 +45,13 @@ dfb $81 -* 62 high-ASCII underscores. Should be one line. +* 62 high-ASCII asterisks. Should be one line. asc "********************************" asc "******************************" dfb $80 -* 96 high-ASCII underscores. Might be converted to "fill". +* 96 high-ASCII asterisks. Might be converted to "fill". asc "********************************" asc "********************************" asc "********************************" diff --git a/SourceGen/SGTestData/Source/20120-char-encoding.S b/SourceGen/SGTestData/Source/20120-char-encoding.S index c5dbe7e..f8541d5 100644 --- a/SourceGen/SGTestData/Source/20120-char-encoding.S +++ b/SourceGen/SGTestData/Source/20120-char-encoding.S @@ -204,5 +204,45 @@ skip_esc nop !byte $a1 !byte $86 +; Test edge case: last character of DCI string is delimiter or invalid +; character, e.g. PETSCII with no ASCII equivalent. +; +; EDIT: format all of these as DCI strings + + !text "ascii",$ff ;invalid end + !byte $86 + + !text $22,"A quote1",$a2 + !text $27,"A quote2",$a7 + !byte $86 + + !xor $80 { + !text $22,"HA quote1",$a2 + !text $27,"HA quote2",$a7 + } + !byte $86 + +; PETSCII stuff + !pet "petscii",$de ;ends with upward arrow ($5e) + !byte $86 + + !pet $22,"a quote1",$a2 + !pet $27,"a quote2",$a7 + !byte $86 + + !byte $dc ;$5c pound sign (UK currency) + !byte $86 + +; ScreenCode stuff + !scr "ScreenCode",$9e ;ends with upward arrow + !byte $86 + + !scr $22,"A quote1",$a2 + !scr $27,"A quote2",$a7 + !byte $86 + + !byte $9c ;$1c pound sign (UK currency) + !byte $86 + skip_dci nop rts