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