mirror of
https://github.com/fadden/6502bench.git
synced 2025-02-18 08:30:28 +00:00
Add C64 encodings to instruction and data operand editors
Both dialogs got a couple extra radio buttons for selection of single character operands. The data operand editor got a combo box that lets you specify how it scans for viable strings. Various string scanning methods were made more generic. This got a little strange with auto-detection of low/high ASCII, but that was mostly a matter of keeping the previous code around as a special case. Made C64 Screen Code DCI strings a thing that works.
This commit is contained in:
parent
176e1ad6af
commit
7bbe5692bd
@ -106,11 +106,12 @@ namespace Asm65 {
|
|||||||
return IsExtendedAscii((byte)(val & 0x7f));
|
return IsExtendedAscii((byte)(val & 0x7f));
|
||||||
}
|
}
|
||||||
public static char ConvertLowAndHighAscii(byte val) {
|
public static char ConvertLowAndHighAscii(byte val) {
|
||||||
if (IsPrintableAscii(val) || IsPrintableHighAscii(val)) {
|
//if (IsPrintableAscii(val) || IsPrintableHighAscii(val)) {
|
||||||
return (char)(val & 0x7f);
|
// return (char)(val & 0x7f);
|
||||||
} else {
|
//} else {
|
||||||
return UNPRINTABLE_CHAR;
|
// return UNPRINTABLE_CHAR;
|
||||||
}
|
//}
|
||||||
|
return ConvertAscii((byte)(val & 0x7f));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -256,5 +257,8 @@ namespace Asm65 {
|
|||||||
return UNPRINTABLE_CHAR;
|
return UNPRINTABLE_CHAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static char ConvertLowAndHighC64ScreenCode(byte val) {
|
||||||
|
return ConvertC64ScreenCode((byte)(val & 0x7f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,12 +152,10 @@ namespace Asm65 {
|
|||||||
new Dictionary<CharEncoding.Encoding, DelimiterDef>();
|
new Dictionary<CharEncoding.Encoding, DelimiterDef>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the specified DelimiterDef, or a default if not found.
|
/// Returns the specified DelimiterDef, or null if not found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DelimiterDef Get(CharEncoding.Encoding enc) {
|
public DelimiterDef Get(CharEncoding.Encoding enc) {
|
||||||
if (!mDelimiters.TryGetValue(enc, out DelimiterDef def)) {
|
mDelimiters.TryGetValue(enc, out DelimiterDef def);
|
||||||
return DOUBLE_QUOTE_DELIM;
|
|
||||||
}
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
public void Set(CharEncoding.Encoding enc, DelimiterDef def) {
|
public void Set(CharEncoding.Encoding enc, DelimiterDef def) {
|
||||||
@ -528,6 +526,10 @@ namespace Asm65 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DelimiterDef delimDef = mFormatConfig.mCharDelimiters.Get(enc);
|
DelimiterDef delimDef = mFormatConfig.mCharDelimiters.Get(enc);
|
||||||
|
if (delimDef == null) {
|
||||||
|
return FormatHexValue(value, 2);
|
||||||
|
}
|
||||||
|
|
||||||
string fmt = delimDef.FormatStr;
|
string fmt = delimDef.FormatStr;
|
||||||
Debug.Assert(fmt != null);
|
Debug.Assert(fmt != null);
|
||||||
|
|
||||||
|
@ -68,6 +68,9 @@ namespace SourceGen {
|
|||||||
|
|
||||||
public const string CLIP_LINE_FORMAT = "clip-line-format";
|
public const string CLIP_LINE_FORMAT = "clip-line-format";
|
||||||
|
|
||||||
|
// Main project view settings.
|
||||||
|
public const string PRVW_RECENT_PROJECT_LIST = "prvw-recent-project-list";
|
||||||
|
|
||||||
// Symbol-list window options.
|
// Symbol-list window options.
|
||||||
public const string SYMWIN_SHOW_USER = "symwin-show-user";
|
public const string SYMWIN_SHOW_USER = "symwin-show-user";
|
||||||
public const string SYMWIN_SHOW_AUTO = "symwin-show-auto";
|
public const string SYMWIN_SHOW_AUTO = "symwin-show-auto";
|
||||||
@ -91,6 +94,9 @@ namespace SourceGen {
|
|||||||
public const string CDLV_FONT_FAMILY = "cdlv-font-family";
|
public const string CDLV_FONT_FAMILY = "cdlv-font-family";
|
||||||
public const string CDLV_FONT_SIZE = "cdlv-font-size";
|
public const string CDLV_FONT_SIZE = "cdlv-font-size";
|
||||||
|
|
||||||
|
// Operand edit settings.
|
||||||
|
public const string OPED_DEFAULT_STRING_ENCODING = "oped-default-string-encoding";
|
||||||
|
|
||||||
// Hex dump viewer settings.
|
// Hex dump viewer settings.
|
||||||
public const string HEXD_ASCII_ONLY = "hexd-ascii-only";
|
public const string HEXD_ASCII_ONLY = "hexd-ascii-only";
|
||||||
public const string HEXD_CHAR_CONV = "hexd-char-conv1";
|
public const string HEXD_CHAR_CONV = "hexd-char-conv1";
|
||||||
@ -105,9 +111,6 @@ namespace SourceGen {
|
|||||||
public const string SRCGEN_LONG_LABEL_NEW_LINE = "srcgen-long-label-new-line";
|
public const string SRCGEN_LONG_LABEL_NEW_LINE = "srcgen-long-label-new-line";
|
||||||
public const string SRCGEN_SHOW_CYCLE_COUNTS = "srcgen-show-cycle-counts";
|
public const string SRCGEN_SHOW_CYCLE_COUNTS = "srcgen-show-cycle-counts";
|
||||||
|
|
||||||
// Main project view settings.
|
|
||||||
public const string PRVW_RECENT_PROJECT_LIST = "prvw-recent-project-list";
|
|
||||||
|
|
||||||
// Assembler settings prefix
|
// Assembler settings prefix
|
||||||
public const string ASM_CONFIG_PREFIX = "asm-config-";
|
public const string ASM_CONFIG_PREFIX = "asm-config-";
|
||||||
|
|
||||||
|
@ -837,43 +837,63 @@ namespace SourceGen {
|
|||||||
/// <param name="fileData">Raw data.</param>
|
/// <param name="fileData">Raw data.</param>
|
||||||
/// <param name="start">Offset of first byte in range.</param>
|
/// <param name="start">Offset of first byte in range.</param>
|
||||||
/// <param name="end">Offset of last byte in range</param>
|
/// <param name="end">Offset of last byte in range</param>
|
||||||
/// <param name="lowAscii">Set to the number of low-ASCII bytes found.</param>
|
/// <param name="charTest">Character test delegate. Must match on both high and
|
||||||
/// <param name="highAscii">Set to the number of high-ASCII bytes found.</param>
|
/// low characters.</param>
|
||||||
/// <param name="nonAscii">Set to the number of non-ASCII bytes found.</param>
|
/// <param name="lowVal">Set to the number of low-range characters found.</param>
|
||||||
public static void CountAsciiBytes(byte[] fileData, int start, int end,
|
/// <param name="highVal">Set to the number of high-range characters found.</param>
|
||||||
out int lowAscii, out int highAscii, out int nonAscii) {
|
/// <param name="nonChar">Set to the number of non-character bytes found.</param>
|
||||||
lowAscii = highAscii = nonAscii = 0;
|
public static void CountHighLowBytes(byte[] fileData, int start, int end,
|
||||||
|
CharEncoding.InclusionTest charTest,
|
||||||
|
out int lowVal, out int highVal, out int nonChar) {
|
||||||
|
lowVal = highVal = nonChar = 0;
|
||||||
|
|
||||||
for (int i = start; i <= end; i++) {
|
for (int i = start; i <= end; i++) {
|
||||||
byte val = fileData[i];
|
byte val = fileData[i];
|
||||||
if (val < 0x20) {
|
if (!charTest(val)) {
|
||||||
nonAscii++;
|
nonChar++;
|
||||||
} else if (val < 0x7f) {
|
} else if ((val & 0x80) == 0) {
|
||||||
lowAscii++;
|
lowVal++;
|
||||||
} else if (val < 0xa0) {
|
|
||||||
nonAscii++;
|
|
||||||
} else if (val < 0xff) {
|
|
||||||
highAscii++;
|
|
||||||
} else {
|
} else {
|
||||||
nonAscii++;
|
highVal++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Counts the number of bytes that match the character test.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileData">Raw data.</param>
|
||||||
|
/// <param name="start">Offset of first byte in range.</param>
|
||||||
|
/// <param name="end">Offset of last byte in range.</param>
|
||||||
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
|
/// <returns>Number of matching characters.</returns>
|
||||||
|
public static int CountCharacterBytes(byte[] fileData, int start, int end,
|
||||||
|
CharEncoding.InclusionTest charTest) {
|
||||||
|
int count = 0;
|
||||||
|
for (int i = start; i <= end; i++) {
|
||||||
|
if (charTest(fileData[i])) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Counts the number of null-terminated strings in the buffer.
|
/// Counts the number of null-terminated strings in the buffer.
|
||||||
///
|
///
|
||||||
/// Zero-length strings are allowed but not included in the count.
|
/// Zero-length strings are allowed but not included in the count.
|
||||||
///
|
///
|
||||||
/// Each string must be either high-ASCII or low-ASCII, not a mix.
|
|
||||||
///
|
|
||||||
/// If any bad data is found, the scan aborts and returns -1.
|
/// If any bad data is found, the scan aborts and returns -1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileData">Raw data.</param>
|
/// <param name="fileData">Raw data.</param>
|
||||||
/// <param name="start">Offset of first byte in range.</param>
|
/// <param name="start">Offset of first byte in range.</param>
|
||||||
/// <param name="end">Offset of last byte in range.</param>
|
/// <param name="end">Offset of last byte in range.</param>
|
||||||
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
|
/// <param name="limitHiBit">If set, the high bit in all character must be the
|
||||||
|
/// same. Used to enforce a single encoding when "low or high ASCII" is used.</param>
|
||||||
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
||||||
public static int RecognizeNullTerminatedStrings(byte[] fileData, int start, int end) {
|
public static int RecognizeNullTerminatedStrings(byte[] fileData, int start, int end,
|
||||||
|
CharEncoding.InclusionTest charTest, bool limitHiBit) {
|
||||||
// Quick test.
|
// Quick test.
|
||||||
if (fileData[end] != 0x00) {
|
if (fileData[end] != 0x00) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -892,6 +912,7 @@ namespace SourceGen {
|
|||||||
stringLen = 0;
|
stringLen = 0;
|
||||||
expectedHiBit = -1;
|
expectedHiBit = -1;
|
||||||
} else {
|
} else {
|
||||||
|
if (limitHiBit) {
|
||||||
if (expectedHiBit == -1) {
|
if (expectedHiBit == -1) {
|
||||||
// First byte in string, set hi/lo expectation.
|
// First byte in string, set hi/lo expectation.
|
||||||
expectedHiBit = val & 0x80;
|
expectedHiBit = val & 0x80;
|
||||||
@ -899,9 +920,9 @@ namespace SourceGen {
|
|||||||
// Mixed ASCII or non-ASCII, fail.
|
// Mixed ASCII or non-ASCII, fail.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val &= 0x7f;
|
}
|
||||||
if (val < 0x20 || val == 0x7f) {
|
if (!charTest(val)) {
|
||||||
// Non-ASCII, fail.
|
// Not a matching character, fail.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
stringLen++;
|
stringLen++;
|
||||||
@ -914,15 +935,17 @@ namespace SourceGen {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Counts strings prefixed with an 8-bit length.
|
/// Counts strings prefixed with an 8-bit length.
|
||||||
///
|
///
|
||||||
/// Each string must be either high-ASCII or low-ASCII, not a mix.
|
|
||||||
///
|
|
||||||
/// Zero-length strings are allowed but not counted.
|
/// Zero-length strings are allowed but not counted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileData">Raw data.</param>
|
/// <param name="fileData">Raw data.</param>
|
||||||
/// <param name="start">Offset of first byte in range.</param>
|
/// <param name="start">Offset of first byte in range.</param>
|
||||||
/// <param name="end">Offset of last byte in range.</param>
|
/// <param name="end">Offset of last byte in range.</param>
|
||||||
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
|
/// <param name="limitHiBit">If set, the high bit in all character must be the
|
||||||
|
/// same. Used to enforce a single encoding when "low or high ASCII" is used.</param>
|
||||||
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
||||||
public static int RecognizeLen8Strings(byte[] fileData, int start, int end) {
|
public static int RecognizeLen8Strings(byte[] fileData, int start, int end,
|
||||||
|
CharEncoding.InclusionTest charTest, bool limitHiBit) {
|
||||||
int posn = start;
|
int posn = start;
|
||||||
int remaining = end - start + 1;
|
int remaining = end - start + 1;
|
||||||
int stringCount = 0;
|
int stringCount = 0;
|
||||||
@ -944,13 +967,12 @@ namespace SourceGen {
|
|||||||
|
|
||||||
while (strLen-- != 0) {
|
while (strLen-- != 0) {
|
||||||
byte val = fileData[posn++];
|
byte val = fileData[posn++];
|
||||||
if ((val & 0x80) != expectedHiBit) {
|
if (limitHiBit && (val & 0x80) != expectedHiBit) {
|
||||||
// Mixed ASCII, fail.
|
// Mixed ASCII, fail.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val &= 0x7f;
|
if (!charTest(val)) {
|
||||||
if (val < 0x20 || val == 0x7f) {
|
// Not a matching character, fail.
|
||||||
// Non-ASCII, fail.
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -962,15 +984,17 @@ namespace SourceGen {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Counts strings prefixed with a 16-bit length.
|
/// Counts strings prefixed with a 16-bit length.
|
||||||
///
|
///
|
||||||
/// Each string must be either high-ASCII or low-ASCII, not a mix.
|
|
||||||
///
|
|
||||||
/// Zero-length strings are allowed but not counted.
|
/// Zero-length strings are allowed but not counted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fileData">Raw data.</param>
|
/// <param name="fileData">Raw data.</param>
|
||||||
/// <param name="start">Offset of first byte in range.</param>
|
/// <param name="start">Offset of first byte in range.</param>
|
||||||
/// <param name="end">Offset of last byte in range.</param>
|
/// <param name="end">Offset of last byte in range.</param>
|
||||||
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
|
/// <param name="limitHiBit">If set, the high bit in all character must be the
|
||||||
|
/// same. Used to enforce a single encoding when "low or high ASCII" is used.</param>
|
||||||
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
||||||
public static int RecognizeLen16Strings(byte[] fileData, int start, int end) {
|
public static int RecognizeLen16Strings(byte[] fileData, int start, int end,
|
||||||
|
CharEncoding.InclusionTest charTest, bool limitHiBit) {
|
||||||
int posn = start;
|
int posn = start;
|
||||||
int remaining = end - start + 1;
|
int remaining = end - start + 1;
|
||||||
int stringCount = 0;
|
int stringCount = 0;
|
||||||
@ -998,13 +1022,12 @@ namespace SourceGen {
|
|||||||
|
|
||||||
while (strLen-- != 0) {
|
while (strLen-- != 0) {
|
||||||
byte val = fileData[posn++];
|
byte val = fileData[posn++];
|
||||||
if ((val & 0x80) != expectedHiBit) {
|
if (limitHiBit && (val & 0x80) != expectedHiBit) {
|
||||||
// Mixed ASCII, fail.
|
// Mixed ASCII, fail.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val &= 0x7f;
|
if (!charTest(val)) {
|
||||||
if (val < 0x20 || val == 0x7f) {
|
// Not a matching character, fail.
|
||||||
// Non-ASCII, fail.
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1020,11 +1043,16 @@ namespace SourceGen {
|
|||||||
/// Each string must be at least two bytes. To reduce false-positives, we require
|
/// Each string must be at least two bytes. To reduce false-positives, we require
|
||||||
/// that all strings have the same hi/lo pattern.
|
/// that all strings have the same hi/lo pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Not useful for C64Petscii, which mixes high/low characters.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="fileData">Raw data.</param>
|
/// <param name="fileData">Raw data.</param>
|
||||||
/// <param name="start">Offset of first byte in range.</param>
|
/// <param name="start">Offset of first byte in range.</param>
|
||||||
/// <param name="end">Offset of last byte in range.</param>
|
/// <param name="end">Offset of last byte in range.</param>
|
||||||
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
/// <returns>Number of strings found, or -1 if bad data identified.</returns>
|
||||||
public static int RecognizeDciStrings(byte[] fileData, int start, int end) {
|
public static int RecognizeDciStrings(byte[] fileData, int start, int end,
|
||||||
|
CharEncoding.InclusionTest charTest) {
|
||||||
int expectedHiBit = fileData[start] & 0x80;
|
int expectedHiBit = fileData[start] & 0x80;
|
||||||
int stringCount = 0;
|
int stringCount = 0;
|
||||||
int stringLen = 0;
|
int stringLen = 0;
|
||||||
@ -1048,9 +1076,8 @@ namespace SourceGen {
|
|||||||
stringLen++;
|
stringLen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
val &= 0x7f;
|
if (!charTest((byte)(val & 0x7f))) {
|
||||||
if (val < 0x20 || val == 0x7f) {
|
// Not a matching character, fail.
|
||||||
// Non-ASCII, fail.
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,8 @@ namespace SourceGen {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="e">Argument from SelectionChanged event.</param>
|
/// <param name="e">Argument from SelectionChanged event.</param>
|
||||||
public void SelectionChanged(SelectionChangedEventArgs e) {
|
public void SelectionChanged(SelectionChangedEventArgs e) {
|
||||||
Debug.WriteLine("SelectionChanged event: Add=" + e.AddedItems.Count +
|
//Debug.WriteLine("SelectionChanged event: Add=" + e.AddedItems.Count +
|
||||||
" Rem=" + e.RemovedItems.Count);
|
// " Rem=" + e.RemovedItems.Count);
|
||||||
foreach (DisplayList.FormattedParts parts in e.AddedItems) {
|
foreach (DisplayList.FormattedParts parts in e.AddedItems) {
|
||||||
Debug.Assert(parts.ListIndex >= 0 && parts.ListIndex < mSelection.Length);
|
Debug.Assert(parts.ListIndex >= 0 && parts.ListIndex < mSelection.Length);
|
||||||
this[parts.ListIndex] = true;
|
this[parts.ListIndex] = true;
|
||||||
|
@ -393,6 +393,7 @@ namespace SourceGen {
|
|||||||
descr += " ???";
|
descr += " ???";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return descr;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (FormatSubType) {
|
switch (FormatSubType) {
|
||||||
|
@ -2359,7 +2359,7 @@ namespace SourceGen {
|
|||||||
/// is selected.</param>
|
/// is selected.</param>
|
||||||
public SelectionState UpdateSelectionState() {
|
public SelectionState UpdateSelectionState() {
|
||||||
int selCount = mMainWin.CodeListView_GetSelectionCount();
|
int selCount = mMainWin.CodeListView_GetSelectionCount();
|
||||||
Debug.WriteLine("UpdateSelectionState: selCount=" + selCount);
|
//Debug.WriteLine("UpdateSelectionState: selCount=" + selCount);
|
||||||
|
|
||||||
SelectionState state = new SelectionState();
|
SelectionState state = new SelectionState();
|
||||||
|
|
||||||
|
@ -318,11 +318,19 @@ namespace SourceGen {
|
|||||||
CharEncoding.Convert charConv;
|
CharEncoding.Convert charConv;
|
||||||
switch (dfd.FormatSubType) {
|
switch (dfd.FormatSubType) {
|
||||||
case FormatDescriptor.SubType.Ascii:
|
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);
|
delDef = delSet.Get(CharEncoding.Encoding.Ascii);
|
||||||
break;
|
break;
|
||||||
case FormatDescriptor.SubType.HighAscii:
|
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);
|
delDef = delSet.Get(CharEncoding.Encoding.HighAscii);
|
||||||
break;
|
break;
|
||||||
case FormatDescriptor.SubType.C64Petscii:
|
case FormatDescriptor.SubType.C64Petscii:
|
||||||
@ -330,7 +338,11 @@ namespace SourceGen {
|
|||||||
delDef = delSet.Get(CharEncoding.Encoding.C64Petscii);
|
delDef = delSet.Get(CharEncoding.Encoding.C64Petscii);
|
||||||
break;
|
break;
|
||||||
case FormatDescriptor.SubType.C64Screen:
|
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);
|
delDef = delSet.Get(CharEncoding.Encoding.C64ScreenCode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -340,13 +352,17 @@ namespace SourceGen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (delDef == null) {
|
||||||
|
delDef = Formatter.DOUBLE_QUOTE_DELIM;
|
||||||
|
}
|
||||||
|
|
||||||
switch (dfd.FormatType) {
|
switch (dfd.FormatType) {
|
||||||
case FormatDescriptor.Type.StringGeneric:
|
case FormatDescriptor.Type.StringGeneric:
|
||||||
// Generic character data.
|
// Generic character data.
|
||||||
popcode = opNames.StrGeneric;
|
popcode = opNames.StrGeneric;
|
||||||
break;
|
break;
|
||||||
case FormatDescriptor.Type.StringReverse:
|
case FormatDescriptor.Type.StringReverse:
|
||||||
// High or low ASCII, full width specified by formatter. Show characters
|
// Character data, full width specified by formatter. Show characters
|
||||||
// in reverse order.
|
// in reverse order.
|
||||||
popcode = opNames.StrReverse;
|
popcode = opNames.StrReverse;
|
||||||
revMode = StringOpFormatter.ReverseMode.FullReverse;
|
revMode = StringOpFormatter.ReverseMode.FullReverse;
|
||||||
@ -377,10 +393,8 @@ namespace SourceGen {
|
|||||||
popcode = opNames.StrLen16;
|
popcode = opNames.StrLen16;
|
||||||
break;
|
break;
|
||||||
case FormatDescriptor.Type.StringDci:
|
case FormatDescriptor.Type.StringDci:
|
||||||
// High or low ASCII, with high bit on last byte flipped. Only useful
|
// High bit on last byte is flipped.
|
||||||
// for ASCII strings.
|
|
||||||
popcode = opNames.StrDci;
|
popcode = opNames.StrDci;
|
||||||
charConv = CharEncoding.ConvertLowAndHighAscii;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
|
@ -112,6 +112,10 @@ limitations under the License.
|
|||||||
<system:String x:Key="str_RuntimeDirNotFoundCaption">RuntimeData Not Found</system:String>
|
<system:String x:Key="str_RuntimeDirNotFoundCaption">RuntimeData Not Found</system:String>
|
||||||
<system:String x:Key="str_SaveBeforeAsm">Please save your project before assembling. The generated source code will be placed in the same directory as the project file.</system:String>
|
<system:String x:Key="str_SaveBeforeAsm">Please save your project before assembling. The generated source code will be placed in the same directory as the project file.</system:String>
|
||||||
<system:String x:Key="str_SaveBeforeAsmCaption">Save Project First</system:String>
|
<system:String x:Key="str_SaveBeforeAsmCaption">Save Project First</system:String>
|
||||||
|
<system:String x:Key="str_ScanLowAscii">Plain ASCII</system:String>
|
||||||
|
<system:String x:Key="str_ScanLowHighAscii">Low or High ASCII</system:String>
|
||||||
|
<system:String x:Key="str_ScanC64Petscii">C64 PETSCII</system:String>
|
||||||
|
<system:String x:Key="str_ScanC64ScreenCode">C64 Screen Code</system:String>
|
||||||
<system:String x:Key="str_SetupSystemSummaryFmt">{1} CPU @ {2} MHz</system:String>
|
<system:String x:Key="str_SetupSystemSummaryFmt">{1} CPU @ {2} MHz</system:String>
|
||||||
<system:String x:Key="str_ShowCol">Show</system:String>
|
<system:String x:Key="str_ShowCol">Show</system:String>
|
||||||
<system:String x:Key="str_StatusReady">Ready</system:String>
|
<system:String x:Key="str_StatusReady">Ready</system:String>
|
||||||
|
@ -205,6 +205,14 @@ namespace SourceGen.Res {
|
|||||||
(string)Application.Current.FindResource("str_SaveBeforeAsm");
|
(string)Application.Current.FindResource("str_SaveBeforeAsm");
|
||||||
public static string SAVE_BEFORE_ASM_CAPTION =
|
public static string SAVE_BEFORE_ASM_CAPTION =
|
||||||
(string)Application.Current.FindResource("str_SaveBeforeAsmCaption");
|
(string)Application.Current.FindResource("str_SaveBeforeAsmCaption");
|
||||||
|
public static string SCAN_LOW_ASCII =
|
||||||
|
(string)Application.Current.FindResource("str_ScanLowAscii");
|
||||||
|
public static string SCAN_LOW_HIGH_ASCII =
|
||||||
|
(string)Application.Current.FindResource("str_ScanLowHighAscii");
|
||||||
|
public static string SCAN_C64_PETSCII =
|
||||||
|
(string)Application.Current.FindResource("str_ScanC64Petscii");
|
||||||
|
public static string SCAN_C64_SCREEN_CODE =
|
||||||
|
(string)Application.Current.FindResource("str_ScanC64ScreenCode");
|
||||||
public static string SETUP_SYSTEM_SUMMARY_FMT =
|
public static string SETUP_SYSTEM_SUMMARY_FMT =
|
||||||
(string)Application.Current.FindResource("str_SetupSystemSummaryFmt");
|
(string)Application.Current.FindResource("str_SetupSystemSummaryFmt");
|
||||||
public static string SHOW_COL =
|
public static string SHOW_COL =
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Copyright 2019 faddenSoft. All Rights Reserved.
|
; Copyright 2019 faddenSoft. All Rights Reserved.
|
||||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
;
|
;
|
||||||
; Assembler: ACME (good PETSCII/screen code support)
|
; Assembler: ACME (for the PETSCII/screen code support)
|
||||||
|
|
||||||
!cpu 65816
|
!cpu 65816
|
||||||
* = $1000
|
* = $1000
|
||||||
@ -28,6 +28,8 @@
|
|||||||
lda #$7f ;EDIT: force to PETSCII
|
lda #$7f ;EDIT: force to PETSCII
|
||||||
lda #$7f ;EDIT: force to screen code
|
lda #$7f ;EDIT: force to screen code
|
||||||
|
|
||||||
|
lda #$0d ;verify the instruction operand editor only allows C64SC
|
||||||
|
|
||||||
; Single letter in a 16-bit immediate
|
; Single letter in a 16-bit immediate
|
||||||
rep #$30
|
rep #$30
|
||||||
!al
|
!al
|
||||||
@ -63,7 +65,7 @@
|
|||||||
; Start with the basics
|
; Start with the basics
|
||||||
!byte $80
|
!byte $80
|
||||||
!text "low ASCII str"
|
!text "low ASCII str"
|
||||||
!byte $80
|
; !byte $80 ; let them run together to test scan / dialog behavior
|
||||||
!xor $80 {
|
!xor $80 {
|
||||||
!text "high ASCII str"
|
!text "high ASCII str"
|
||||||
}
|
}
|
||||||
|
@ -512,6 +512,9 @@ namespace SourceGen.WpfGui {
|
|||||||
private void ImportDelimiters(Formatter.DelimiterSet delSet, DelimiterTextBoxes[] boxarr) {
|
private void ImportDelimiters(Formatter.DelimiterSet delSet, DelimiterTextBoxes[] boxarr) {
|
||||||
foreach (DelimiterTextBoxes boxes in boxarr) {
|
foreach (DelimiterTextBoxes boxes in boxarr) {
|
||||||
Formatter.DelimiterDef def = delSet.Get(boxes.mEncoding);
|
Formatter.DelimiterDef def = delSet.Get(boxes.mEncoding);
|
||||||
|
if (def == null) {
|
||||||
|
def = Formatter.DOUBLE_QUOTE_DELIM;
|
||||||
|
}
|
||||||
boxes.mPrefix.Text = def.Prefix;
|
boxes.mPrefix.Text = def.Prefix;
|
||||||
boxes.mOpen.Text = "" + def.OpenDelim;
|
boxes.mOpen.Text = "" + def.OpenDelim;
|
||||||
boxes.mClose.Text = "" + def.CloseDelim;
|
boxes.mClose.Text = "" + def.CloseDelim;
|
||||||
|
@ -33,8 +33,8 @@ limitations under the License.
|
|||||||
<system:String x:Key="str_SingleGroup">Select data format ({0} bytes selected):</system:String>
|
<system:String x:Key="str_SingleGroup">Select data format ({0} bytes selected):</system:String>
|
||||||
<system:String x:Key="str_MultiGroup">Select data format ({0} bytes selected in {1} groups):</system:String>
|
<system:String x:Key="str_MultiGroup">Select data format ({0} bytes selected in {1} groups):</system:String>
|
||||||
|
|
||||||
<system:String x:Key="str_StringMixed">Mixed ASCII ({0} bytes) and non-ASCII ({1} bytes)</system:String>
|
<system:String x:Key="str_StringMixed">Mixed character ({0} bytes) and non-character ({1} bytes)</system:String>
|
||||||
<system:String x:Key="str_StringMixedReverse">Reversed ASCII ({0} bytes) and non-ASCII ({1} bytes)</system:String>
|
<system:String x:Key="str_StringMixedReverse">Reversed character ({0} bytes) and non-character ({1} bytes)</system:String>
|
||||||
<system:String x:Key="str_StringNullTerm">Null-terminated strings ({0})</system:String>
|
<system:String x:Key="str_StringNullTerm">Null-terminated strings ({0})</system:String>
|
||||||
<system:String x:Key="str_StringLen8">Strings prefixed with 8-bit length ({0})</system:String>
|
<system:String x:Key="str_StringLen8">Strings prefixed with 8-bit length ({0})</system:String>
|
||||||
<system:String x:Key="str_StringLen16">Strings prefixed with 16-bit length ({0})</system:String>
|
<system:String x:Key="str_StringLen16">Strings prefixed with 16-bit length ({0})</system:String>
|
||||||
@ -64,29 +64,44 @@ limitations under the License.
|
|||||||
<RadioButton Name="radio32BitLittle" GroupName="Main" Content="32-bit words, little-endian" Margin="0,4,0,0"
|
<RadioButton Name="radio32BitLittle" GroupName="Main" Content="32-bit words, little-endian" Margin="0,4,0,0"
|
||||||
Checked="MainGroup_CheckedChanged"/>
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<GroupBox Name="simpleDisplayAsGroupBox" Grid.Column="1" Header="Display As..." Margin="16,0,0,0">
|
<GroupBox Name="simpleDisplayAsGroupBox" Grid.Column="1" Header="Display As..." Margin="16,0,0,0"
|
||||||
|
Padding="2,4">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Grid.Column="0">
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Grid.Column="0" Grid.Row="0">
|
||||||
<RadioButton Name="radioSimpleDataHex" GroupName="Display" Content="Hex"
|
<RadioButton Name="radioSimpleDataHex" GroupName="Display" Content="Hex"
|
||||||
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
<RadioButton Name="radioSimpleDataDecimal" GroupName="Display" Content="Decimal"
|
<RadioButton Name="radioSimpleDataDecimal" GroupName="Display" Content="Decimal"
|
||||||
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
Margin="0,4,18,0" Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
<RadioButton Name="radioSimpleDataBinary" GroupName="Display" Content="Binary"
|
<RadioButton Name="radioSimpleDataBinary" GroupName="Display" Content="Binary"
|
||||||
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
<RadioButton Name="radioSimpleDataAscii" GroupName="Display" Content="ASCII"
|
<RadioButton Name="radioSimpleDataAddress" GroupName="Display" Content="_Address"
|
||||||
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Column="1">
|
<StackPanel Grid.Column="1" Grid.Row="0">
|
||||||
<RadioButton Name="radioSimpleDataAddress" GroupName="Display" Content="_Address"
|
<RadioButton Name="radioSimpleDataAscii" GroupName="Display"
|
||||||
Margin="12,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
Content="ASCII (low or high) character"
|
||||||
|
Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
|
<RadioButton Name="radioSimpleDataPetscii" GroupName="Display"
|
||||||
|
Content="C64 PETSCII character"
|
||||||
|
Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
|
<RadioButton Name="radioSimpleDataScreenCode" GroupName="Display"
|
||||||
|
Content="C64 Screen character"
|
||||||
|
Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2">
|
||||||
<RadioButton Name="radioSimpleDataSymbolic" GroupName="Display" Content="_Symbolic reference"
|
<RadioButton Name="radioSimpleDataSymbolic" GroupName="Display" Content="_Symbolic reference"
|
||||||
Margin="12,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
Margin="0,4,0,0" Checked="SimpleDisplay_CheckedChanged"/>
|
||||||
<TextBox Name="symbolEntryTextBox" Margin="32,4,0,0" TextChanged="SymbolEntryTextBox_TextChanged"/>
|
<TextBox Name="symbolEntryTextBox" Margin="20,4,0,0" TextChanged="SymbolEntryTextBox_TextChanged"/>
|
||||||
<StackPanel Orientation="Horizontal" Margin="32,4,0,0"
|
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="20,4,0,0"
|
||||||
IsEnabled="{Binding ElementName=radioSimpleDataSymbolic, Path=IsChecked}">
|
IsEnabled="{Binding ElementName=radioSimpleDataSymbolic, Path=IsChecked}">
|
||||||
<RadioButton Name="radioSymbolPartLow" GroupName="Part" Content="Low"/>
|
<RadioButton Name="radioSymbolPartLow" GroupName="Part" Content="Low"/>
|
||||||
<RadioButton Name="radioSymbolPartHigh" GroupName="Part" Content="High" Margin="8,0,0,0"/>
|
<RadioButton Name="radioSymbolPartHigh" GroupName="Part" Content="High" Margin="8,0,0,0"/>
|
||||||
@ -106,6 +121,12 @@ limitations under the License.
|
|||||||
|
|
||||||
<TextBlock Text="String" Margin="0,12,0,0"/>
|
<TextBlock Text="String" Margin="0,12,0,0"/>
|
||||||
<Rectangle HorizontalAlignment="Stretch" Fill="LightGray" Height="2"/>
|
<Rectangle HorizontalAlignment="Stretch" Fill="LightGray" Height="2"/>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="Character encoding:" Margin="0,7,0,0"/>
|
||||||
|
<ComboBox Name="stringEncodingComboBox" Width="150" Margin="8,4,0,4"
|
||||||
|
ItemsSource="{Binding StringEncodingItems}" DisplayMemberPath="Name"
|
||||||
|
SelectionChanged="StringEncodingComboBox_SelectionChanged"/>
|
||||||
|
</StackPanel>
|
||||||
<RadioButton Name="radioStringMixed" GroupName="Main" Margin="0,4,0,0"
|
<RadioButton Name="radioStringMixed" GroupName="Main" Margin="0,4,0,0"
|
||||||
Content="{StaticResource str_StringMixed}"
|
Content="{StaticResource str_StringMixed}"
|
||||||
Checked="MainGroup_CheckedChanged"/>
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
|
@ -21,7 +21,9 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
using Asm65;
|
||||||
using CommonUtil;
|
using CommonUtil;
|
||||||
|
using TextScanMode = SourceGen.ProjectProperties.AnalysisParameters.TextScanMode;
|
||||||
|
|
||||||
namespace SourceGen.WpfGui {
|
namespace SourceGen.WpfGui {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -77,18 +79,27 @@ namespace SourceGen.WpfGui {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private Asm65.Formatter mFormatter;
|
private Asm65.Formatter mFormatter;
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Set this during initial control configuration, so we know to ignore the CheckedChanged
|
|
||||||
///// events.
|
|
||||||
///// </summary>
|
|
||||||
//private bool mIsInitialSetup;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to true if, during the initial setup, the format defined by FirstFormatDescriptor
|
/// Set to true if, during the initial setup, the format defined by FirstFormatDescriptor
|
||||||
/// was unavailable.
|
/// was unavailable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool mPreferredFormatUnavailable;
|
private bool mPreferredFormatUnavailable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text encoding combo box item. We use the same TextScanMode enum that the
|
||||||
|
/// uncategorized data analyzer uses.
|
||||||
|
/// </summary>
|
||||||
|
public class StringEncodingItem {
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public TextScanMode Mode { get; private set; }
|
||||||
|
|
||||||
|
public StringEncodingItem(string name, TextScanMode mode) {
|
||||||
|
Name = name;
|
||||||
|
Mode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public StringEncodingItem[] StringEncodingItems { get; private set; }
|
||||||
|
|
||||||
// INotifyPropertyChanged implementation
|
// INotifyPropertyChanged implementation
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||||
@ -107,6 +118,17 @@ namespace SourceGen.WpfGui {
|
|||||||
mFormatter = formatter;
|
mFormatter = formatter;
|
||||||
mSelection = trs;
|
mSelection = trs;
|
||||||
mFirstFormatDescriptor = firstDesc;
|
mFirstFormatDescriptor = firstDesc;
|
||||||
|
|
||||||
|
StringEncodingItems = new StringEncodingItem[] {
|
||||||
|
new StringEncodingItem(Res.Strings.SCAN_LOW_ASCII,
|
||||||
|
TextScanMode.LowAscii),
|
||||||
|
new StringEncodingItem(Res.Strings.SCAN_LOW_HIGH_ASCII,
|
||||||
|
TextScanMode.LowHighAscii),
|
||||||
|
new StringEncodingItem(Res.Strings.SCAN_C64_PETSCII,
|
||||||
|
TextScanMode.C64Petscii),
|
||||||
|
new StringEncodingItem(Res.Strings.SCAN_C64_SCREEN_CODE,
|
||||||
|
TextScanMode.C64ScreenCode),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
@ -116,6 +138,9 @@ namespace SourceGen.WpfGui {
|
|||||||
// Disable any radio buttons that won't work.
|
// Disable any radio buttons that won't work.
|
||||||
AnalyzeRanges();
|
AnalyzeRanges();
|
||||||
|
|
||||||
|
// This gets invoked a bit later, from the "selection changed" callback.
|
||||||
|
//AnalyzeStringRanges(TextScanMode.LowHighAscii);
|
||||||
|
|
||||||
// Configure the dialog from the FormatDescriptor, if one is available.
|
// Configure the dialog from the FormatDescriptor, if one is available.
|
||||||
Debug.WriteLine("First FD: " + mFirstFormatDescriptor);
|
Debug.WriteLine("First FD: " + mFirstFormatDescriptor);
|
||||||
SetControlsFromDescriptor(mFirstFormatDescriptor);
|
SetControlsFromDescriptor(mFirstFormatDescriptor);
|
||||||
@ -169,6 +194,36 @@ namespace SourceGen.WpfGui {
|
|||||||
UpdateControls();
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the string encoding combo box to an item that matches the specified mode. If
|
||||||
|
/// the mode can't be found, an arbitrary entry will be chosen.
|
||||||
|
/// </summary>
|
||||||
|
private void SetStringEncoding(TextScanMode mode) {
|
||||||
|
StringEncodingItem choice = null;
|
||||||
|
foreach (StringEncodingItem item in StringEncodingItems) {
|
||||||
|
if (item.Mode == mode) {
|
||||||
|
choice = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (choice == null) {
|
||||||
|
choice = StringEncodingItems[1];
|
||||||
|
}
|
||||||
|
stringEncodingComboBox.SelectedItem = choice;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StringEncodingComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||||
|
if (!IsLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringEncodingItem item = (StringEncodingItem)stringEncodingComboBox.SelectedItem;
|
||||||
|
AnalyzeStringRanges(item.Mode);
|
||||||
|
UpdateControls();
|
||||||
|
|
||||||
|
AppSettings.Global.SetEnum(AppSettings.OPED_DEFAULT_STRING_ENCODING,
|
||||||
|
typeof(TextScanMode), (int)item.Mode);
|
||||||
|
}
|
||||||
|
|
||||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||||
CreateDescriptorListFromControls();
|
CreateDescriptorListFromControls();
|
||||||
FormatDescriptor.DebugDumpSortedList(Results);
|
FormatDescriptor.DebugDumpSortedList(Results);
|
||||||
@ -207,7 +262,14 @@ namespace SourceGen.WpfGui {
|
|||||||
bool focusOnSymbol = !simpleDisplayAsGroupBox.IsEnabled && wantStyle;
|
bool focusOnSymbol = !simpleDisplayAsGroupBox.IsEnabled && wantStyle;
|
||||||
simpleDisplayAsGroupBox.IsEnabled = wantStyle;
|
simpleDisplayAsGroupBox.IsEnabled = wantStyle;
|
||||||
if (wantStyle) {
|
if (wantStyle) {
|
||||||
radioSimpleDataAscii.IsEnabled = IsRawAsciiCompatible(simpleWidth, isBigEndian);
|
// Because this covers multiple items in a data area, we allow the
|
||||||
|
// "extended" set, which includes some control characters.
|
||||||
|
radioSimpleDataAscii.IsEnabled = IsCompatibleWithCharSet(simpleWidth,
|
||||||
|
isBigEndian, CharEncoding.IsExtendedLowOrHighAscii);
|
||||||
|
radioSimpleDataPetscii.IsEnabled = IsCompatibleWithCharSet(simpleWidth,
|
||||||
|
isBigEndian, CharEncoding.IsExtendedC64Petscii);
|
||||||
|
radioSimpleDataScreenCode.IsEnabled = IsCompatibleWithCharSet(simpleWidth,
|
||||||
|
isBigEndian, CharEncoding.IsExtendedC64ScreenCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable the symbolic reference entry box if the "display as" group is enabled.
|
// Enable the symbolic reference entry box if the "display as" group is enabled.
|
||||||
@ -263,13 +325,6 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
IEnumerator<TypedRangeSet.TypedRange> iter = mSelection.RangeListIterator;
|
IEnumerator<TypedRangeSet.TypedRange> iter = mSelection.RangeListIterator;
|
||||||
|
|
||||||
int mixedAsciiOkCount = 0;
|
|
||||||
int mixedAsciiNotCount = 0;
|
|
||||||
int nullTermStringCount = 0;
|
|
||||||
int len8StringCount = 0;
|
|
||||||
int len16StringCount = 0;
|
|
||||||
int dciStringCount = 0;
|
|
||||||
|
|
||||||
// For each range, check to see if the data within qualifies for the various
|
// For each range, check to see if the data within qualifies for the various
|
||||||
// options. If any of them fail to meet the criteria, the option is disabled
|
// options. If any of them fail to meet the criteria, the option is disabled
|
||||||
// for all ranges.
|
// for all ranges.
|
||||||
@ -277,7 +332,7 @@ namespace SourceGen.WpfGui {
|
|||||||
TypedRangeSet.TypedRange rng = iter.Current;
|
TypedRangeSet.TypedRange rng = iter.Current;
|
||||||
Debug.WriteLine("Testing [" + rng.Low + ", " + rng.High + "]");
|
Debug.WriteLine("Testing [" + rng.Low + ", " + rng.High + "]");
|
||||||
|
|
||||||
// Start with the easy ones. Single-byte and dense are always enabled.
|
// Note single-byte and dense are always enabled.
|
||||||
|
|
||||||
int count = rng.High - rng.Low + 1;
|
int count = rng.High - rng.Low + 1;
|
||||||
Debug.Assert(count > 0);
|
Debug.Assert(count > 0);
|
||||||
@ -305,18 +360,68 @@ namespace SourceGen.WpfGui {
|
|||||||
} else {
|
} else {
|
||||||
radioFill.IsEnabled = false;
|
radioFill.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Analyzes the selection to see which string formatting options are suitable.
|
||||||
|
/// Disables radio buttons and updates labels.
|
||||||
|
///
|
||||||
|
/// Call this when the character encoding selection changes.
|
||||||
|
/// </summary>
|
||||||
|
private void AnalyzeStringRanges(TextScanMode scanMode) {
|
||||||
|
Debug.WriteLine("Analyzing string ranges");
|
||||||
|
Debug.Assert(IsLoaded);
|
||||||
|
|
||||||
|
int mixedCharOkCount = 0;
|
||||||
|
int mixedCharNotCount = 0;
|
||||||
|
int nullTermStringCount = 0;
|
||||||
|
int len8StringCount = 0;
|
||||||
|
int len16StringCount = 0;
|
||||||
|
int dciStringCount = 0;
|
||||||
|
|
||||||
|
CharEncoding.InclusionTest charTest;
|
||||||
|
switch (scanMode) {
|
||||||
|
case TextScanMode.LowAscii:
|
||||||
|
charTest = CharEncoding.IsExtendedAscii;
|
||||||
|
break;
|
||||||
|
case TextScanMode.LowHighAscii:
|
||||||
|
charTest = CharEncoding.IsExtendedLowOrHighAscii;
|
||||||
|
break;
|
||||||
|
case TextScanMode.C64Petscii:
|
||||||
|
charTest = CharEncoding.IsExtendedC64Petscii;
|
||||||
|
break;
|
||||||
|
case TextScanMode.C64ScreenCode:
|
||||||
|
charTest = CharEncoding.IsExtendedC64ScreenCode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Debug.Assert(false);
|
||||||
|
charTest = CharEncoding.IsExtendedAscii;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
radioStringMixed.IsEnabled = true;
|
||||||
|
radioStringMixedReverse.IsEnabled = true;
|
||||||
|
radioStringNullTerm.IsEnabled = (scanMode != TextScanMode.C64ScreenCode);
|
||||||
|
radioStringLen8.IsEnabled = true;
|
||||||
|
radioStringLen16.IsEnabled = true;
|
||||||
|
radioStringDci.IsEnabled = (scanMode != TextScanMode.C64Petscii);
|
||||||
|
|
||||||
|
IEnumerator<TypedRangeSet.TypedRange> iter = mSelection.RangeListIterator;
|
||||||
|
while (iter.MoveNext()) {
|
||||||
|
TypedRangeSet.TypedRange rng = iter.Current;
|
||||||
|
Debug.WriteLine("Testing [" + rng.Low + ", " + rng.High + "]");
|
||||||
|
|
||||||
// See if there's enough string data to make it worthwhile. We use an
|
// See if there's enough string data to make it worthwhile. We use an
|
||||||
// arbitrary threshold of 2+ ASCII characters, and require twice as many
|
// arbitrary threshold of 2+ printable characters, and require twice as many
|
||||||
// ASCII as non-ASCII. We arbitrarily require the strings to be either
|
// printable as non-printable.
|
||||||
// high or low ASCII, and treat the other as non-ASCII. (We could relax
|
|
||||||
// this -- we generate separate items for each string and non-ASCII chunk --
|
|
||||||
// but I'm trying to hide the option when the buffer doesn't really seem
|
|
||||||
// to be holding strings. Could replace with some sort of minimum string
|
|
||||||
// length requirement?)
|
|
||||||
if (radioStringMixed.IsEnabled) {
|
if (radioStringMixed.IsEnabled) {
|
||||||
|
if (scanMode == TextScanMode.LowHighAscii) {
|
||||||
|
// We use a special test that counts low, high, and non-ASCII.
|
||||||
|
// Whichever form of ASCII has the highest count is the winner, and
|
||||||
|
// the loser is counted as non-ASCII.
|
||||||
int asciiCount;
|
int asciiCount;
|
||||||
DataAnalysis.CountAsciiBytes(mFileData, rng.Low, rng.High,
|
DataAnalysis.CountHighLowBytes(mFileData, rng.Low, rng.High, charTest,
|
||||||
out int lowAscii, out int highAscii, out int nonAscii);
|
out int lowAscii, out int highAscii, out int nonAscii);
|
||||||
if (highAscii > lowAscii) {
|
if (highAscii > lowAscii) {
|
||||||
asciiCount = highAscii;
|
asciiCount = highAscii;
|
||||||
@ -328,23 +433,37 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
if (asciiCount >= 2 && asciiCount >= nonAscii * 2) {
|
if (asciiCount >= 2 && asciiCount >= nonAscii * 2) {
|
||||||
// Looks good
|
// Looks good
|
||||||
mixedAsciiOkCount += asciiCount;
|
mixedCharOkCount += asciiCount;
|
||||||
mixedAsciiNotCount += nonAscii;
|
mixedCharNotCount += nonAscii;
|
||||||
} else {
|
} else {
|
||||||
// Fail
|
// Fail
|
||||||
radioStringMixed.IsEnabled = false;
|
radioStringMixed.IsEnabled = false;
|
||||||
radioStringMixedReverse.IsEnabled = false;
|
radioStringMixedReverse.IsEnabled = false;
|
||||||
mixedAsciiOkCount = mixedAsciiNotCount = -1;
|
mixedCharOkCount = mixedCharNotCount = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int matchCount = DataAnalysis.CountCharacterBytes(mFileData,
|
||||||
|
rng.Low, rng.High, charTest);
|
||||||
|
int missCount = (rng.High - rng.Low + 1) - matchCount;
|
||||||
|
if (matchCount >= 2 && matchCount >= missCount * 2) {
|
||||||
|
mixedCharOkCount += matchCount;
|
||||||
|
mixedCharNotCount += missCount;
|
||||||
|
} else {
|
||||||
|
// Fail
|
||||||
|
radioStringMixed.IsEnabled = false;
|
||||||
|
radioStringMixedReverse.IsEnabled = false;
|
||||||
|
mixedCharOkCount = mixedCharNotCount = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for null-terminated strings. Zero-length strings are allowed, but
|
// Check for null-terminated strings. Zero-length strings are allowed, but
|
||||||
// not counted -- we want to have some actual character data. Individual
|
// not counted -- we want to have some actual character data. Individual
|
||||||
// strings need to be entirely high-ASCII or low-ASCII, but not all strings
|
// ASCII strings need to be entirely high-ASCII or low-ASCII, but not all strings
|
||||||
// in a region have to be the same.
|
// in a region have to be the same.
|
||||||
if (radioStringNullTerm.IsEnabled) {
|
if (radioStringNullTerm.IsEnabled) {
|
||||||
int strCount = DataAnalysis.RecognizeNullTerminatedStrings(mFileData,
|
int strCount = DataAnalysis.RecognizeNullTerminatedStrings(mFileData,
|
||||||
rng.Low, rng.High);
|
rng.Low, rng.High, charTest, scanMode == TextScanMode.LowHighAscii);
|
||||||
if (strCount > 0) {
|
if (strCount > 0) {
|
||||||
nullTermStringCount += strCount;
|
nullTermStringCount += strCount;
|
||||||
} else {
|
} else {
|
||||||
@ -355,7 +474,8 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
// Check for strings prefixed with an 8-bit length.
|
// Check for strings prefixed with an 8-bit length.
|
||||||
if (radioStringLen8.IsEnabled) {
|
if (radioStringLen8.IsEnabled) {
|
||||||
int strCount = DataAnalysis.RecognizeLen8Strings(mFileData, rng.Low, rng.High);
|
int strCount = DataAnalysis.RecognizeLen8Strings(mFileData, rng.Low, rng.High,
|
||||||
|
charTest, scanMode == TextScanMode.LowHighAscii);
|
||||||
if (strCount > 0) {
|
if (strCount > 0) {
|
||||||
len8StringCount += strCount;
|
len8StringCount += strCount;
|
||||||
} else {
|
} else {
|
||||||
@ -366,7 +486,8 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
// Check for strings prefixed with a 16-bit length.
|
// Check for strings prefixed with a 16-bit length.
|
||||||
if (radioStringLen16.IsEnabled) {
|
if (radioStringLen16.IsEnabled) {
|
||||||
int strCount = DataAnalysis.RecognizeLen16Strings(mFileData, rng.Low, rng.High);
|
int strCount = DataAnalysis.RecognizeLen16Strings(mFileData, rng.Low, rng.High,
|
||||||
|
charTest, scanMode == TextScanMode.LowHighAscii);
|
||||||
if (strCount > 0) {
|
if (strCount > 0) {
|
||||||
len16StringCount += strCount;
|
len16StringCount += strCount;
|
||||||
} else {
|
} else {
|
||||||
@ -375,10 +496,11 @@ namespace SourceGen.WpfGui {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for DCI strings. All strings within a single range must have the
|
// Check for DCI strings. All strings within the entire range must have the
|
||||||
// same "polarity", e.g. low ASCII terminated by high ASCII.
|
// same "polarity", e.g. low ASCII terminated by high ASCII.
|
||||||
if (radioStringDci.IsEnabled) {
|
if (radioStringDci.IsEnabled) {
|
||||||
int strCount = DataAnalysis.RecognizeDciStrings(mFileData, rng.Low, rng.High);
|
int strCount = DataAnalysis.RecognizeDciStrings(mFileData, rng.Low, rng.High,
|
||||||
|
charTest);
|
||||||
if (strCount > 0) {
|
if (strCount > 0) {
|
||||||
dciStringCount += strCount;
|
dciStringCount += strCount;
|
||||||
} else {
|
} else {
|
||||||
@ -390,15 +512,16 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
// Update the dialog with string and character counts, summed across all regions.
|
// Update the dialog with string and character counts, summed across all regions.
|
||||||
|
|
||||||
|
string fmt;
|
||||||
const string UNSUP_STR = "xx";
|
const string UNSUP_STR = "xx";
|
||||||
fmt = (string)FindResource("str_StringMixed");
|
fmt = (string)FindResource("str_StringMixed");
|
||||||
string revfmt = (string)FindResource("str_StringMixedReverse");
|
string revfmt = (string)FindResource("str_StringMixedReverse");
|
||||||
if (mixedAsciiOkCount > 0) {
|
if (mixedCharOkCount > 0) {
|
||||||
Debug.Assert(radioStringMixed.IsEnabled);
|
Debug.Assert(radioStringMixed.IsEnabled);
|
||||||
radioStringMixed.Content = string.Format(fmt,
|
radioStringMixed.Content = string.Format(fmt,
|
||||||
mixedAsciiOkCount, mixedAsciiNotCount);
|
mixedCharOkCount, mixedCharNotCount);
|
||||||
radioStringMixedReverse.Content = string.Format(revfmt,
|
radioStringMixedReverse.Content = string.Format(revfmt,
|
||||||
mixedAsciiOkCount, mixedAsciiNotCount);
|
mixedCharOkCount, mixedCharNotCount);
|
||||||
} else {
|
} else {
|
||||||
Debug.Assert(!radioStringMixed.IsEnabled);
|
Debug.Assert(!radioStringMixed.IsEnabled);
|
||||||
radioStringMixed.Content = string.Format(fmt, UNSUP_STR, UNSUP_STR);
|
radioStringMixed.Content = string.Format(fmt, UNSUP_STR, UNSUP_STR);
|
||||||
@ -440,32 +563,40 @@ namespace SourceGen.WpfGui {
|
|||||||
Debug.Assert(!radioStringDci.IsEnabled);
|
Debug.Assert(!radioStringDci.IsEnabled);
|
||||||
radioStringDci.Content = string.Format(fmt, UNSUP_STR);
|
radioStringDci.Content = string.Format(fmt, UNSUP_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this invalidated the selected item, reset to Default.
|
||||||
|
if ((radioStringMixed.IsChecked == true && !radioStringMixed.IsEnabled) ||
|
||||||
|
(radioStringMixedReverse.IsChecked == true && !radioStringMixedReverse.IsEnabled) ||
|
||||||
|
(radioStringNullTerm.IsChecked == true && !radioStringNullTerm.IsEnabled) ||
|
||||||
|
(radioStringLen8.IsChecked == true && !radioStringLen8.IsEnabled) ||
|
||||||
|
(radioStringLen8.IsChecked == true && !radioStringLen8.IsEnabled) ||
|
||||||
|
(radioStringDci.IsChecked == true && !radioStringDci.IsEnabled)) {
|
||||||
|
|
||||||
|
Debug.WriteLine("Previous selection invalidated");
|
||||||
|
radioDefaultFormat.IsChecked = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the data in the buffer can be represented as ASCII values.
|
/// Determines whether the data in the buffer can be represented as character values.
|
||||||
/// Using ".DD1 'A'" for 0x41 is obvious, but we also allow ".DD2 'A'" for
|
/// Using ".DD1 'A'" for 0x41 is obvious, but we also allow ".DD2 'A'" for
|
||||||
/// 0x41 0x00. 16-bit character constants are more likely as intermediate
|
/// 0x41 0x00. 16-bit character constants are more likely as intermediate
|
||||||
/// operands, but could be found in data areas.
|
/// operands, but could be found in data areas.
|
||||||
///
|
|
||||||
/// High and low ASCII are allowed, and may be freely mixed.
|
|
||||||
///
|
|
||||||
/// Testing explicitly is probably excessive, and possibly counter-productive if
|
|
||||||
/// the user is trying to flag an area that is a mix of ASCII and non-ASCII and
|
|
||||||
/// just wants hex for the rest, but we'll give it a try.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="wordWidth">Number of bytes per character.</param>
|
/// <param name="wordWidth">Number of bytes per character.</param>
|
||||||
/// <param name="isBigEndian">Word endian-ness.</param>
|
/// <param name="isBigEndian">Word endian-ness.</param>
|
||||||
/// <returns>True if data in all regions can be represented as high or low ASCII.</returns>
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
private bool IsRawAsciiCompatible(int wordWidth, bool isBigEndian) {
|
/// <returns>True if data in all regions can be represented as a character.</returns>
|
||||||
|
private bool IsCompatibleWithCharSet(int wordWidth, bool isBigEndian,
|
||||||
|
CharEncoding.InclusionTest charTest) {
|
||||||
IEnumerator<TypedRangeSet.TypedRange> iter = mSelection.RangeListIterator;
|
IEnumerator<TypedRangeSet.TypedRange> iter = mSelection.RangeListIterator;
|
||||||
while (iter.MoveNext()) {
|
while (iter.MoveNext()) {
|
||||||
TypedRangeSet.TypedRange rng = iter.Current;
|
TypedRangeSet.TypedRange rng = iter.Current;
|
||||||
Debug.Assert(((rng.High - rng.Low + 1) / wordWidth) * wordWidth ==
|
Debug.Assert(((rng.High - rng.Low + 1) / wordWidth) * wordWidth ==
|
||||||
rng.High - rng.Low + 1);
|
rng.High - rng.Low + 1);
|
||||||
for (int i = rng.Low; i <= rng.High; i += wordWidth) {
|
for (int i = rng.Low; i <= rng.High; i += wordWidth) {
|
||||||
int val = RawData.GetWord(mFileData, rng.Low, wordWidth, isBigEndian);
|
int val = RawData.GetWord(mFileData, i, wordWidth, isBigEndian);
|
||||||
if (val < 0x20 || (val >= 0x7f && val < 0xa0) || val >= 0xff) {
|
if (val != (byte)val || !charTest((byte)val)) {
|
||||||
// bad value, fail
|
// bad value, fail
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -485,11 +616,22 @@ namespace SourceGen.WpfGui {
|
|||||||
radioSimpleDataHex.IsChecked = true;
|
radioSimpleDataHex.IsChecked = true;
|
||||||
radioSymbolPartLow.IsChecked = true;
|
radioSymbolPartLow.IsChecked = true;
|
||||||
|
|
||||||
|
// Get the previous mode selected in the combo box. If the format descriptor
|
||||||
|
// doesn't specify a string, we'll use this.
|
||||||
|
TextScanMode textMode = (TextScanMode)AppSettings.Global.GetEnum(
|
||||||
|
AppSettings.OPED_DEFAULT_STRING_ENCODING, typeof(TextScanMode),
|
||||||
|
(int)TextScanMode.LowHighAscii);
|
||||||
|
|
||||||
if (dfd == null) {
|
if (dfd == null) {
|
||||||
radioDefaultFormat.IsChecked = true;
|
radioDefaultFormat.IsChecked = true;
|
||||||
|
SetStringEncoding(textMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dfd.IsString) {
|
||||||
|
textMode = TextScanModeFromDescriptor(dfd);
|
||||||
|
}
|
||||||
|
|
||||||
RadioButton preferredFormat;
|
RadioButton preferredFormat;
|
||||||
|
|
||||||
switch (dfd.FormatType) {
|
switch (dfd.FormatType) {
|
||||||
@ -529,11 +671,14 @@ namespace SourceGen.WpfGui {
|
|||||||
break;
|
break;
|
||||||
case FormatDescriptor.SubType.Ascii:
|
case FormatDescriptor.SubType.Ascii:
|
||||||
case FormatDescriptor.SubType.HighAscii:
|
case FormatDescriptor.SubType.HighAscii:
|
||||||
case FormatDescriptor.SubType.C64Petscii:
|
|
||||||
case FormatDescriptor.SubType.C64Screen:
|
|
||||||
// TODO(petscii): update UI
|
|
||||||
radioSimpleDataAscii.IsChecked = true;
|
radioSimpleDataAscii.IsChecked = true;
|
||||||
break;
|
break;
|
||||||
|
case FormatDescriptor.SubType.C64Petscii:
|
||||||
|
radioSimpleDataPetscii.IsChecked = true;
|
||||||
|
break;
|
||||||
|
case FormatDescriptor.SubType.C64Screen:
|
||||||
|
radioSimpleDataScreenCode.IsChecked = true;
|
||||||
|
break;
|
||||||
case FormatDescriptor.SubType.Address:
|
case FormatDescriptor.SubType.Address:
|
||||||
radioSimpleDataAddress.IsChecked = true;
|
radioSimpleDataAddress.IsChecked = true;
|
||||||
break;
|
break;
|
||||||
@ -601,6 +746,24 @@ namespace SourceGen.WpfGui {
|
|||||||
mPreferredFormatUnavailable = true;
|
mPreferredFormatUnavailable = true;
|
||||||
radioDefaultFormat.IsChecked = true;
|
radioDefaultFormat.IsChecked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetStringEncoding(textMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextScanMode TextScanModeFromDescriptor(FormatDescriptor dfd) {
|
||||||
|
Debug.Assert(dfd.IsString);
|
||||||
|
switch (dfd.FormatSubType) {
|
||||||
|
case FormatDescriptor.SubType.Ascii:
|
||||||
|
case FormatDescriptor.SubType.HighAscii:
|
||||||
|
return TextScanMode.LowHighAscii;
|
||||||
|
case FormatDescriptor.SubType.C64Petscii:
|
||||||
|
return TextScanMode.C64Petscii;
|
||||||
|
case FormatDescriptor.SubType.C64Screen:
|
||||||
|
return TextScanMode.C64ScreenCode;
|
||||||
|
default:
|
||||||
|
Debug.Assert(false);
|
||||||
|
return TextScanMode.LowHighAscii;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Setup
|
#endregion Setup
|
||||||
@ -623,6 +786,33 @@ namespace SourceGen.WpfGui {
|
|||||||
WeakSymbolRef symbolRef = null;
|
WeakSymbolRef symbolRef = null;
|
||||||
int chunkLength = -1;
|
int chunkLength = -1;
|
||||||
|
|
||||||
|
FormatDescriptor.SubType charSubType;
|
||||||
|
CharEncoding.InclusionTest charTest;
|
||||||
|
StringEncodingItem item = (StringEncodingItem)stringEncodingComboBox.SelectedItem;
|
||||||
|
switch (item.Mode) {
|
||||||
|
case TextScanMode.LowAscii:
|
||||||
|
charSubType = FormatDescriptor.SubType.Ascii;
|
||||||
|
charTest = CharEncoding.IsExtendedAscii;
|
||||||
|
break;
|
||||||
|
case TextScanMode.LowHighAscii:
|
||||||
|
charSubType = FormatDescriptor.SubType.ASCII_GENERIC;
|
||||||
|
charTest = CharEncoding.IsExtendedLowOrHighAscii;
|
||||||
|
break;
|
||||||
|
case TextScanMode.C64Petscii:
|
||||||
|
charSubType = FormatDescriptor.SubType.C64Petscii;
|
||||||
|
charTest = CharEncoding.IsExtendedC64Petscii;
|
||||||
|
break;
|
||||||
|
case TextScanMode.C64ScreenCode:
|
||||||
|
charSubType = FormatDescriptor.SubType.C64Screen;
|
||||||
|
charTest = CharEncoding.IsExtendedC64ScreenCode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Debug.Assert(false);
|
||||||
|
charSubType = FormatDescriptor.SubType.ASCII_GENERIC;
|
||||||
|
charTest = CharEncoding.IsExtendedLowOrHighAscii;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Decode the "display as" panel, if it's relevant.
|
// Decode the "display as" panel, if it's relevant.
|
||||||
if (radioSimpleDataHex.IsEnabled) {
|
if (radioSimpleDataHex.IsEnabled) {
|
||||||
if (radioSimpleDataHex.IsChecked == true) {
|
if (radioSimpleDataHex.IsChecked == true) {
|
||||||
@ -632,8 +822,11 @@ namespace SourceGen.WpfGui {
|
|||||||
} else if (radioSimpleDataBinary.IsChecked == true) {
|
} else if (radioSimpleDataBinary.IsChecked == true) {
|
||||||
subType = FormatDescriptor.SubType.Binary;
|
subType = FormatDescriptor.SubType.Binary;
|
||||||
} else if (radioSimpleDataAscii.IsChecked == true) {
|
} else if (radioSimpleDataAscii.IsChecked == true) {
|
||||||
// TODO(petscii): add PETSCII buttons
|
|
||||||
subType = FormatDescriptor.SubType.ASCII_GENERIC;
|
subType = FormatDescriptor.SubType.ASCII_GENERIC;
|
||||||
|
} else if (radioSimpleDataPetscii.IsChecked == true) {
|
||||||
|
subType = FormatDescriptor.SubType.C64Petscii;
|
||||||
|
} else if (radioSimpleDataScreenCode.IsChecked == true) {
|
||||||
|
subType = FormatDescriptor.SubType.C64Screen;
|
||||||
} else if (radioSimpleDataAddress.IsChecked == true) {
|
} else if (radioSimpleDataAddress.IsChecked == true) {
|
||||||
subType = FormatDescriptor.SubType.Address;
|
subType = FormatDescriptor.SubType.Address;
|
||||||
} else if (radioSimpleDataSymbolic.IsChecked == true) {
|
} else if (radioSimpleDataSymbolic.IsChecked == true) {
|
||||||
@ -683,26 +876,23 @@ namespace SourceGen.WpfGui {
|
|||||||
} else if (radioFill.IsChecked == true) {
|
} else if (radioFill.IsChecked == true) {
|
||||||
type = FormatDescriptor.Type.Fill;
|
type = FormatDescriptor.Type.Fill;
|
||||||
} else if (radioStringMixed.IsChecked == true) {
|
} else if (radioStringMixed.IsChecked == true) {
|
||||||
// TODO(petscii): encoding format will come from a combo box; that determines
|
|
||||||
// the subType and the arg to the string-creation functions, which use the
|
|
||||||
// appropriate char encoding methods to break up the strings
|
|
||||||
type = FormatDescriptor.Type.StringGeneric;
|
type = FormatDescriptor.Type.StringGeneric;
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = charSubType;
|
||||||
} else if (radioStringMixedReverse.IsChecked == true) {
|
} else if (radioStringMixedReverse.IsChecked == true) {
|
||||||
type = FormatDescriptor.Type.StringReverse;
|
type = FormatDescriptor.Type.StringReverse;
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = charSubType;
|
||||||
} else if (radioStringNullTerm.IsChecked == true) {
|
} else if (radioStringNullTerm.IsChecked == true) {
|
||||||
type = FormatDescriptor.Type.StringNullTerm;
|
type = FormatDescriptor.Type.StringNullTerm;
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = charSubType;
|
||||||
} else if (radioStringLen8.IsChecked == true) {
|
} else if (radioStringLen8.IsChecked == true) {
|
||||||
type = FormatDescriptor.Type.StringL8;
|
type = FormatDescriptor.Type.StringL8;
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = charSubType;
|
||||||
} else if (radioStringLen16.IsChecked == true) {
|
} else if (radioStringLen16.IsChecked == true) {
|
||||||
type = FormatDescriptor.Type.StringL16;
|
type = FormatDescriptor.Type.StringL16;
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = charSubType;
|
||||||
} else if (radioStringDci.IsChecked == true) {
|
} else if (radioStringDci.IsChecked == true) {
|
||||||
type = FormatDescriptor.Type.StringDci;
|
type = FormatDescriptor.Type.StringDci;
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = charSubType;
|
||||||
} else {
|
} else {
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
// default/none
|
// default/none
|
||||||
@ -715,11 +905,12 @@ namespace SourceGen.WpfGui {
|
|||||||
while (iter.MoveNext()) {
|
while (iter.MoveNext()) {
|
||||||
TypedRangeSet.TypedRange rng = iter.Current;
|
TypedRangeSet.TypedRange rng = iter.Current;
|
||||||
|
|
||||||
// TODO(petscii): handle encoding on all four calls
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FormatDescriptor.Type.StringGeneric:
|
case FormatDescriptor.Type.StringGeneric:
|
||||||
|
CreateMixedStringEntries(rng.Low, rng.High, type, subType, charTest);
|
||||||
|
break;
|
||||||
case FormatDescriptor.Type.StringReverse:
|
case FormatDescriptor.Type.StringReverse:
|
||||||
CreateMixedStringEntries(rng.Low, rng.High, type, subType);
|
CreateMixedStringEntries(rng.Low, rng.High, type, subType, charTest);
|
||||||
break;
|
break;
|
||||||
case FormatDescriptor.Type.StringNullTerm:
|
case FormatDescriptor.Type.StringNullTerm:
|
||||||
CreateCStringEntries(rng.Low, rng.High, type, subType);
|
CreateCStringEntries(rng.Low, rng.High, type, subType);
|
||||||
@ -794,25 +985,35 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates one or more FormatDescriptor entries for the specified range, adding them
|
/// Creates one or more FormatDescriptor entries for the specified range, adding them
|
||||||
/// to the Results list.
|
/// to the Results list. Runs of character data are output as generic strings, while any
|
||||||
|
/// non-character data is output as individual bytes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is the only string create function that accepts a mix of valid and invalid
|
||||||
|
/// characters.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="low">Offset of first byte in range.</param>
|
/// <param name="low">Offset of first byte in range.</param>
|
||||||
/// <param name="high">Offset of last byte in range.</param>
|
/// <param name="high">Offset of last byte in range.</param>
|
||||||
|
/// <param name="type">String type (Generic or Reverse).</param>
|
||||||
/// <param name="subType">String sub-type.</param>
|
/// <param name="subType">String sub-type.</param>
|
||||||
|
/// <param name="charTest">Character test delegate.</param>
|
||||||
private void CreateMixedStringEntries(int low, int high, FormatDescriptor.Type type,
|
private void CreateMixedStringEntries(int low, int high, FormatDescriptor.Type type,
|
||||||
FormatDescriptor.SubType subType) {
|
FormatDescriptor.SubType subType, CharEncoding.InclusionTest charTest) {
|
||||||
int stringStart = -1;
|
int stringStart = -1;
|
||||||
int highBit = 0;
|
|
||||||
int cur;
|
int cur;
|
||||||
|
|
||||||
|
if (subType == FormatDescriptor.SubType.ASCII_GENERIC) {
|
||||||
|
int highBit = 0;
|
||||||
for (cur = low; cur <= high; cur++) {
|
for (cur = low; cur <= high; cur++) {
|
||||||
byte val = mFileData[cur];
|
byte val = mFileData[cur];
|
||||||
if (CommonUtil.TextUtil.IsHiLoAscii(val)) {
|
if (charTest(val)) {
|
||||||
// is ASCII
|
// is ASCII
|
||||||
if (stringStart >= 0) {
|
if (stringStart >= 0) {
|
||||||
// was in a string
|
// was in a string
|
||||||
if (highBit != (val & 0x80)) {
|
if (highBit != (val & 0x80)) {
|
||||||
// end of string due to high bit flip, output
|
// end of string due to high bit flip, output
|
||||||
CreateStringOrByte(stringStart, cur - stringStart, subType);
|
CreateGenericStringOrByte(stringStart, cur - stringStart,
|
||||||
|
type, subType);
|
||||||
// start a new string
|
// start a new string
|
||||||
stringStart = cur;
|
stringStart = cur;
|
||||||
} else {
|
} else {
|
||||||
@ -827,36 +1028,75 @@ namespace SourceGen.WpfGui {
|
|||||||
// not ASCII
|
// not ASCII
|
||||||
if (stringStart >= 0) {
|
if (stringStart >= 0) {
|
||||||
// was in a string, output it
|
// was in a string, output it
|
||||||
CreateStringOrByte(stringStart, cur - stringStart, subType);
|
CreateGenericStringOrByte(stringStart, cur - stringStart,
|
||||||
|
type, subType);
|
||||||
stringStart = -1;
|
stringStart = -1;
|
||||||
}
|
}
|
||||||
// output as single byte
|
// output as single byte
|
||||||
CreateByteFD(cur, FormatDescriptor.SubType.Hex);
|
CreateByteFD(cur, FormatDescriptor.SubType.Hex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (cur = low; cur <= high; cur++) {
|
||||||
|
byte val = mFileData[cur];
|
||||||
|
if (charTest(val)) {
|
||||||
|
// is character
|
||||||
|
if (stringStart < 0) {
|
||||||
|
// mark this as the start of the string
|
||||||
|
stringStart = cur;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// not character
|
||||||
if (stringStart >= 0) {
|
if (stringStart >= 0) {
|
||||||
// close out the string
|
// was in a string, output it
|
||||||
CreateStringOrByte(stringStart, cur - stringStart, subType);
|
CreateGenericStringOrByte(stringStart, cur - stringStart,
|
||||||
|
type, subType);
|
||||||
|
stringStart = -1;
|
||||||
|
}
|
||||||
|
// output as single byte
|
||||||
|
CreateByteFD(cur, FormatDescriptor.SubType.Hex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (stringStart >= 0) {
|
||||||
|
// close out the string
|
||||||
|
CreateGenericStringOrByte(stringStart, cur - stringStart, type, subType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FormatDescriptor.SubType ResolveAsciiGeneric(int offset,
|
||||||
|
FormatDescriptor.SubType subType) {
|
||||||
|
if (subType == FormatDescriptor.SubType.ASCII_GENERIC) {
|
||||||
|
if ((mFileData[offset] & 0x80) != 0) {
|
||||||
|
subType = FormatDescriptor.SubType.HighAscii;
|
||||||
|
} else {
|
||||||
|
subType = FormatDescriptor.SubType.Ascii;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return subType;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a format descriptor for ASCII data. If the data is only one byte long,
|
/// Creates a format descriptor for character data. If the data is only one byte long,
|
||||||
/// a single-byte ASCII char item is emitted instead.
|
/// a single-byte character item is emitted instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">Offset of first byte.</param>
|
/// <param name="offset">Offset of first byte.</param>
|
||||||
/// <param name="length">Length of string.</param>
|
/// <param name="length">Length of string.</param>
|
||||||
/// <param name="subType">String sub-type.</param>
|
/// <param name="type">String type (Generic or Reverse).</param>
|
||||||
private void CreateStringOrByte(int offset, int length, FormatDescriptor.SubType subType) {
|
/// <param name="subType">String sub-type. If set to ASCII_GENERIC, this will
|
||||||
|
/// refine the sub-type.</param>
|
||||||
|
private void CreateGenericStringOrByte(int offset, int length,
|
||||||
|
FormatDescriptor.Type type, FormatDescriptor.SubType subType) {
|
||||||
Debug.Assert(length > 0);
|
Debug.Assert(length > 0);
|
||||||
|
subType = ResolveAsciiGeneric(offset, subType);
|
||||||
if (length == 1) {
|
if (length == 1) {
|
||||||
// Single byte, output as single char rather than 1-byte string. We use the
|
// Single byte, output as single char rather than 1-byte string. We use the
|
||||||
// same encoding as the rest of the string.
|
// same encoding as the rest of the string.
|
||||||
CreateByteFD(offset, subType);
|
CreateByteFD(offset, subType);
|
||||||
} else {
|
} else {
|
||||||
FormatDescriptor dfd;
|
FormatDescriptor dfd;
|
||||||
dfd = FormatDescriptor.Create(length,
|
dfd = FormatDescriptor.Create(length, type, subType);
|
||||||
FormatDescriptor.Type.StringGeneric, subType);
|
|
||||||
Results.Add(offset, dfd);
|
Results.Add(offset, dfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -886,7 +1126,7 @@ namespace SourceGen.WpfGui {
|
|||||||
if (mFileData[i] == 0x00) {
|
if (mFileData[i] == 0x00) {
|
||||||
// End of string. Zero-length strings are allowed.
|
// End of string. Zero-length strings are allowed.
|
||||||
FormatDescriptor dfd = FormatDescriptor.Create(
|
FormatDescriptor dfd = FormatDescriptor.Create(
|
||||||
i - startOffset + 1, type, subType);
|
i - startOffset + 1, type, ResolveAsciiGeneric(startOffset, subType));
|
||||||
Results.Add(startOffset, dfd);
|
Results.Add(startOffset, dfd);
|
||||||
startOffset = i + 1;
|
startOffset = i + 1;
|
||||||
} else {
|
} else {
|
||||||
@ -917,7 +1157,8 @@ namespace SourceGen.WpfGui {
|
|||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
// Zero-length strings are allowed.
|
// Zero-length strings are allowed.
|
||||||
FormatDescriptor dfd = FormatDescriptor.Create(length, type, subType);
|
FormatDescriptor dfd = FormatDescriptor.Create(length, type,
|
||||||
|
ResolveAsciiGeneric(i, subType));
|
||||||
Results.Add(i, dfd);
|
Results.Add(i, dfd);
|
||||||
i += length;
|
i += length;
|
||||||
}
|
}
|
||||||
@ -948,8 +1189,9 @@ namespace SourceGen.WpfGui {
|
|||||||
if ((val & 0x80) == endMask) {
|
if ((val & 0x80) == endMask) {
|
||||||
// found the end of a string
|
// found the end of a string
|
||||||
int length = (i - stringStart) + 1;
|
int length = (i - stringStart) + 1;
|
||||||
FormatDescriptor dfd = FormatDescriptor.Create(length, type, subType);
|
FormatDescriptor dfd = FormatDescriptor.Create(length, type,
|
||||||
Results.Add(stringStart < i ? stringStart : i, dfd);
|
ResolveAsciiGeneric(stringStart, subType));
|
||||||
|
Results.Add(stringStart, dfd);
|
||||||
stringStart = i + 1;
|
stringStart = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,11 @@ limitations under the License.
|
|||||||
Checked="MainGroup_CheckedChanged"/>
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
<RadioButton Name="binaryButton" GroupName="Format" Content="Binary" Margin="0,2,0,0"
|
<RadioButton Name="binaryButton" GroupName="Format" Content="Binary" Margin="0,2,0,0"
|
||||||
Checked="MainGroup_CheckedChanged"/>
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
<RadioButton Name="asciiButton" GroupName="Format" Content="ASCII character" Margin="0,2,0,0"
|
<RadioButton Name="asciiButton" GroupName="Format" Content="ASCII (low or high) character" Margin="0,2,0,0"
|
||||||
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
|
<RadioButton Name="petsciiButton" GroupName="Format" Content="C64 PETSCII character" Margin="0,2,0,0"
|
||||||
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
|
<RadioButton Name="screenCodeButton" GroupName="Format" Content="C64 Screen character" Margin="0,2,0,0"
|
||||||
Checked="MainGroup_CheckedChanged"/>
|
Checked="MainGroup_CheckedChanged"/>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
@ -171,8 +171,19 @@ namespace SourceGen.WpfGui {
|
|||||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
mIsInitialSetup = true;
|
mIsInitialSetup = true;
|
||||||
|
|
||||||
// Can this be represented as high or low ASCII?
|
// Can this be represented as a character? We only allow the printable set
|
||||||
asciiButton.IsEnabled = CommonUtil.TextUtil.IsHiLoAscii(mOperandValue);
|
// here, not the extended set (which includes control characters).
|
||||||
|
if (mOperandValue == (byte) mOperandValue) {
|
||||||
|
asciiButton.IsEnabled =
|
||||||
|
CharEncoding.IsPrintableLowOrHighAscii((byte)mOperandValue);
|
||||||
|
petsciiButton.IsEnabled =
|
||||||
|
CharEncoding.IsPrintableC64Petscii((byte)mOperandValue);
|
||||||
|
screenCodeButton.IsEnabled =
|
||||||
|
CharEncoding.IsPrintableC64ScreenCode((byte)mOperandValue);
|
||||||
|
} else {
|
||||||
|
asciiButton.IsEnabled = petsciiButton.IsEnabled = screenCodeButton.IsEnabled =
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the dialog from the FormatDescriptor, if one is available.
|
// Configure the dialog from the FormatDescriptor, if one is available.
|
||||||
SetControlsFromDescriptor(FormatDescriptor);
|
SetControlsFromDescriptor(FormatDescriptor);
|
||||||
@ -475,9 +486,14 @@ namespace SourceGen.WpfGui {
|
|||||||
break;
|
break;
|
||||||
case FormatDescriptor.SubType.Ascii:
|
case FormatDescriptor.SubType.Ascii:
|
||||||
case FormatDescriptor.SubType.HighAscii:
|
case FormatDescriptor.SubType.HighAscii:
|
||||||
// TODO(petscii): encoding
|
|
||||||
asciiButton.IsChecked = true;
|
asciiButton.IsChecked = true;
|
||||||
break;
|
break;
|
||||||
|
case FormatDescriptor.SubType.C64Petscii:
|
||||||
|
petsciiButton.IsChecked = true;
|
||||||
|
break;
|
||||||
|
case FormatDescriptor.SubType.C64Screen:
|
||||||
|
screenCodeButton.IsChecked = true;
|
||||||
|
break;
|
||||||
case FormatDescriptor.SubType.Symbol:
|
case FormatDescriptor.SubType.Symbol:
|
||||||
Debug.Assert(dfd.HasSymbol);
|
Debug.Assert(dfd.HasSymbol);
|
||||||
symbolButton.IsChecked = true;
|
symbolButton.IsChecked = true;
|
||||||
@ -555,12 +571,15 @@ namespace SourceGen.WpfGui {
|
|||||||
} else if (binaryButton.IsChecked == true) {
|
} else if (binaryButton.IsChecked == true) {
|
||||||
subType = FormatDescriptor.SubType.Binary;
|
subType = FormatDescriptor.SubType.Binary;
|
||||||
} else if (asciiButton.IsChecked == true) {
|
} else if (asciiButton.IsChecked == true) {
|
||||||
// TODO(petscii): encoding
|
|
||||||
if (mOperandValue > 0x7f) {
|
if (mOperandValue > 0x7f) {
|
||||||
subType = FormatDescriptor.SubType.HighAscii;
|
subType = FormatDescriptor.SubType.HighAscii;
|
||||||
} else {
|
} else {
|
||||||
subType = FormatDescriptor.SubType.Ascii;
|
subType = FormatDescriptor.SubType.Ascii;
|
||||||
}
|
}
|
||||||
|
} else if (petsciiButton.IsChecked == true) {
|
||||||
|
subType = FormatDescriptor.SubType.C64Petscii;
|
||||||
|
} else if (screenCodeButton.IsChecked == true) {
|
||||||
|
subType = FormatDescriptor.SubType.C64Screen;
|
||||||
} else if (symbolButton.IsChecked == true) {
|
} else if (symbolButton.IsChecked == true) {
|
||||||
subType = FormatDescriptor.SubType.Symbol;
|
subType = FormatDescriptor.SubType.Symbol;
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,11 +38,6 @@ limitations under the License.
|
|||||||
<system:String x:Key="str_65C02">WDC W65C02S</system:String>
|
<system:String x:Key="str_65C02">WDC W65C02S</system:String>
|
||||||
<system:String x:Key="str_65816">WDC W65C816S</system:String>
|
<system:String x:Key="str_65816">WDC W65C816S</system:String>
|
||||||
|
|
||||||
<system:String x:Key="str_LowAscii">Plain ASCII</system:String>
|
|
||||||
<system:String x:Key="str_LowHighAscii">Plain or High ASCII</system:String>
|
|
||||||
<system:String x:Key="str_C64Petscii">C64 PETSCII</system:String>
|
|
||||||
<system:String x:Key="str_C64ScreenCode">C64 Screen Code</system:String>
|
|
||||||
|
|
||||||
<system:String x:Key="str_DisableStringScan">None (disabled)</system:String>
|
<system:String x:Key="str_DisableStringScan">None (disabled)</system:String>
|
||||||
|
|
||||||
<system:String x:Key="str_AutoLabelSimple">Simple ("L1234")</system:String>
|
<system:String x:Key="str_AutoLabelSimple">Simple ("L1234")</system:String>
|
||||||
|
@ -97,13 +97,13 @@ namespace SourceGen.WpfGui {
|
|||||||
new CpuItem((string)FindResource("str_65816"), CpuDef.CpuType.Cpu65816),
|
new CpuItem((string)FindResource("str_65816"), CpuDef.CpuType.Cpu65816),
|
||||||
};
|
};
|
||||||
DefaultTextScanModeItems = new DefaultTextScanMode[] {
|
DefaultTextScanModeItems = new DefaultTextScanMode[] {
|
||||||
new DefaultTextScanMode((string)FindResource("str_LowAscii"),
|
new DefaultTextScanMode(Res.Strings.SCAN_LOW_ASCII,
|
||||||
TextScanMode.LowAscii),
|
TextScanMode.LowAscii),
|
||||||
new DefaultTextScanMode((string)FindResource("str_LowHighAscii"),
|
new DefaultTextScanMode(Res.Strings.SCAN_LOW_HIGH_ASCII,
|
||||||
TextScanMode.LowHighAscii),
|
TextScanMode.LowHighAscii),
|
||||||
new DefaultTextScanMode((string)FindResource("str_C64Petscii"),
|
new DefaultTextScanMode(Res.Strings.SCAN_C64_PETSCII,
|
||||||
TextScanMode.C64Petscii),
|
TextScanMode.C64Petscii),
|
||||||
new DefaultTextScanMode((string)FindResource("str_C64ScreenCode"),
|
new DefaultTextScanMode(Res.Strings.SCAN_C64_SCREEN_CODE,
|
||||||
TextScanMode.C64ScreenCode),
|
TextScanMode.C64ScreenCode),
|
||||||
};
|
};
|
||||||
MinCharsItems = new MinCharsItem[] {
|
MinCharsItems = new MinCharsItem[] {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user