Implemented local variable editing. Operands that have a local
variable reference, or are eligible to have one, can now be edited
directly from the instruction operand edit dialog.
Also, updated the code list double-click handler so that, if you
double-click on the opcode of an instruction that uses a local
variable reference, the selection and view will jump to the place
where that variable was defined.
Also, tweaked the way the References window refers to references
to an address that didn't use a symbol at that address. Updated
the explanation in the manual, which was a bit confusing.
Also, fixed some odds and ends in the manual.
Also, fixed a nasty infinite recursion bug (issue #47).
Rearrange the UI elements, and convert the code-behind to a more
XAML-style form. The basic stuff works, but the old "shortcut"
system is still in the process of being replaced.
This hits most of the edge cases, but doesn't exercise the two
duplicate name situations (var name same as user label, var name
same as project/platform symbol).
Also, fixed a bug in the EditDefSymbol uniqueness check where it
was comparing a symbol to itself.
Variables are now handled properly end-to-end, except for label
uniquification. So cc65 and ACME can't yet handle a file that
redefines a local variable.
This required a bunch of plumbing, but I think it came out okay.
We now generate FormatDescriptors with WeakSymbolRefs for direct
page references that match variable table entries.
LocalVariableTable got a rewrite. We need to be unique in both
name and address, but for the address we have to take the width into
account as well. We also want to sort the display by address
rather than name. (Some people might want it sorted by name, but
we can worry about that some other time.)
Updated the DefSymbol editor to require value uniqueness. Note
addresses and constants exist in separate namespaces.
The various symbols are added to the SymbolTable so that uniqueness
checks work correctly. This also allows the operand generation to
appear to work, but it doesn't yet handle redefinition of symbols.
Multi-line item, with one .eq line per variable definition. Add
one header line if "clear previous" is set.
Also, limit variable values to 0-255 in the editor. This is
somewhat arbitrary, but I think a focus on DP is useful.
This involved adding a list to the DisasmProject, creating a new
UndoableChange type, and writing the project file serialization
code. While doing the latter I realized that the new Width field
was redundant with the FormatDescriptor Length field, and removed it.
I added a placeholder line type, but we're not yet showing the
table in the display list. (To edit the tables you just have to
know where they are.)
The table editor is now editing the table, and the DefSymbol editor
now asks for the Width data when editing a local var.
This also moves EditDefSymbol closer to proper WPF style, with
bound properties for the input fields.
No changes yet to serialization or analysis.
Fixed a minor bug in GenerateLineList that would cause a blank line
to disappear under certain circumstances. Harmless, but odd.
Added a width property to DefSymbol.
Updated comments.
I didn't think it made sense, but I found something that used it,
so apparently it's a thing. This updates the operand editor to
let you choose PETSCII+DCI, and updates the assemblers to handle
it correctly (really just 64tass, since the others either don't
have a DCI directive or don't deal with PETSCII at all).
Changed the char-encoding sample from "bad dcI" to "pet dcI", and
updated the documentation.
String operands used to be simple -- each line had 62 characters
plus two hard-coded non-ASCII delimiters -- but now we're mixing
character and hex data, so we can't use simple math to tell where
the lines will break. We want to render them and keep the result
around until some dependency changes, e.g. different delimiters
or a change to the pseudo-op table.
Also, cleaned up LineListGen a little. It had some methods that
were declared static because they were expected to be shared, but
that never happened.
Also, fixed a bug in GatherEntityCounts where multi-line items were
being scanned multiple times.
The PseudoOpNames class is increasingly being used in situations
where mutability is undesirable. This change makes instances
immutable, eliminating the Copy() method and adding a constructor
that takes a Dictionary. The serialization code now operates on a
Dictionary instead of the class properties, but the JSON encoding is
identical, so this doesn't invalidate app settings file data.
Added an equality test to PseudoOpNames. In LineListGen, don't
reset the line list if the names haven't actually changed.
Use a table lookup for C64 character conversions. I figure that
should be faster than multiple conditionals on a modern x64 system.
Fixed a 64tass generator issue where we tried to query project
properties in a call that might not have a project available
(specifically, getting FormatConfig values out of the generator for
use in the "quick set" buttons for Display Format).
Fixed a regression test harness issue where, if the assembler reported
success but didn't actually generate output, an exception would be
thrown that halted the tests.
Increased the width of text entry fields on the Pseudo-Op tab of app
settings. The previous 8-character limit wasn't wide enough to hold
ACME's "!pseudopc". Also, use TrimEnd() to remove trailing spaces
(leading spaces are still allowed).
In the last couple of months, Win10 started stalling for a fraction
of a second when executing assemblers. It doesn't do this every
time; mostly it happens if it has been a while since the assembler
was run. My guess is this has to do with changes to the built-in
malware scanner. Whatever the case, we now change the mouse pointer
to a wait cursor while updating the assembler version cache.
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.
A delimiter definition is four strings (prefix, open, close, suffix)
that are concatenated with the character or string data to form an
operand. A delimiter set is a collection of delimiter definitions,
with separate entries for each character encoding.
This is a convenient way to configure Formatter objects, import and
export data from the app settings file, and manage the UI needed to
allow the user to customize how things look.
The full set of options didn't fit on the first app settings tab, so
there's now a separate tab just for specifying character and string
delimiters. (This might be overkill, but there are various plausible
scenarios that make use of it.)
The delimiters for on-screen display of strings can now be
configured.
It's not quite the same as the character encoding -- sometimes we
want a mix of things -- so it gets its own enum. The value is
saved to the project file, but not actually used yet.
Also, moved some combo box strings into XAML resources.
Remove left/right arrow PNGs. Remove duplicate copies of icon.
Tweak some comments. Set application icon. Adjust padding on
group boxes in first tab of app settings.
The previous code output a character in single-quotes if it was
standard ASCII, double-quotes if high ASCII, or hex if it was neither
of those. If a flag was set, high ASCII would also be output as
hex.
The new system takes the character value and an encoding identifier.
The identifier selects the character converter and delimiter
pattern, and puts the two together to generate the operand.
While doing this I realized that I could trivially support high
ASCII character arguments in all assemblers by setting the delimiter
pattern to "'#' | $80".
In FormatDescriptor, I had previously renamed the "Ascii" sub-type
"LowAscii" so it wouldn't be confused, but I dislike filling the
project file with "LowAscii" when "Ascii" is more accurate and less
confusing. So I switched it back, and we now check the project
file version number when deciding what to do with an ASCII item.
The CharEncoding tests/converters were also renamed.
Moved the default delimiter patterns to the string table.
Widened the delimiter pattern input fields slightly. Added a read-
only TextBox with assorted non-typewriter quotes and things so
people have something to copy text from.
High ASCII and other encodings will be noted in the operand field,
not the opcode, so we no longer need these.
This removes the six input fields from the Pseudo-Op tab of app
settings. Values were stored as a serialized class in settings,
which generally works correctly as far as forward/backward
compatibility goes, so no worries there.
This also adds four "delimiter pattern" fields to the Code View tab,
allowing the user to customize how encoded strings are marked up
for the code list. The values aren't actually used yet.
Also, fixed an issue where changes to text fields on the Pseudo-Op
tab weren't raising the dirty flag.
We've been treating ASCII strings and instruction/data operands as
ambiguous, resolving low vs. high when generating output for the
display or assembler. This change splits it into two separate
formats, simplifying output generation.
The UI will continue to treat low/high ASCII as as single thing,
selecting the format appropriately based on the data. There's no
reason to have two radio buttons that are never both enabled.
The data operand string functions need some additional work, but
that overlaps substantially with the upcoming PETSCII changes, so
for now all strings set by the data operand editor are low ASCII.
The file format has changed again, but since there hasn't been a
release since the previous change, I'm leaving the file format
at v2. Code has been added to resolve the ASCII mode when loading
a v1 project file.
This removes some complexity from the assembly code generators.
We used to use type="String", with the sub-type indicating whether
the string was null-terminated, prefixed with a length, or whatever.
This didn't leave much room for specifying a character encoding,
which is orthogonal to the sub-type.
What we actually want is to have the type specify the string type,
and then have the sub-type determine the character encoding. These
sub-types can also be used with the Numeric type to specify the
encoding of character operands.
This change updates the enum definitions and the various bits of
code that use them, but does not add any code for working with
non-ASCII character encodings.
The project file version number was incremented to 2, since the new
FormatDescriptor serialization is mildly incompatible with the old.
(Won't explode, but it'll post a complaint and ignore the stuff
it doesn't recognize.)
While I was at it, I finished removing DciReverse. It's still part
of the 2005-string-types regression test, which currently fails
because the generated source doesn't match.
WDM <arg> now works. MVN/MVP are still broken. Correct code is
generated for whichever version of the assembler is configured.
Regression tests updated for new version.
Also, fixed a UI bug where manual edits to the assembler path were
being ignored.
- Updated the tutorial to track changes to WPF, and to clarify
existing content.
- Fixed Ctrl+H Ctrl+C, which was getting masked by the Copy command
handler.
- Fixed initial selection of address in Set Address.
- MakeDist now copies CommonWPF.dll.
- Spent a bunch of time tracking down a null-pointer deref that only
happened when you didn't start with a config file. Fixed.
- The NPE was causing the program to exit without any sort of useful
diagnostic, so I added an uncaught exception handler that writes
the crash to a text file in the current directory.
- Added a trace listener definition to App.config that writes log
messages to a file, but it can't generally be enabled at runtime
because you can't write files from inside the sandbox. So it's
there but commented out.
- Made the initial size of the main window a little wider.