Modified "jump to" code to understand address range start/end lines.
If there are multiple starts or ends at the same offset, we jump to
the first one in the set, which is suboptimal but simpler to do.
Simplified the API, embedding GoToMode in the Location object (which
is where it really needs to be, to make fwd/back work right).
Updated HTML export to grey out addresses in NON_ADDR sections.
Changed default pseudo-op strings for address regions to ".addrs" and
".adrend", after trying a bunch of things that were worse. Added
definitions for region-end pseudo-ops to Merlin32 and cc65 for display
on screen.
Added regression test 20260 for address region pre-labels.
Fixed handling of leading underscores in platform/project symbols.
These need to be escaped in 64tass output. Updated regression test
20170-external-symbols to check it.
Implemented address region pre-labels. These are useful if the code is
relocating a block from address A to address B, because the code that
does the copying refers to both the "before" address and the "after"
address. Previously you'd give the block the "after" address and the
"before" would just appears as hex, because it's effectively an
external address.
Pre-labels are shown on screen with their address, but no other fields.
Showing the address makes it easy to see the label's value, which isn't
always obvious right before a .arstart. The labels are suppressed if the
address value evaluates to non-addressable.
This defines a new type of symbol, which is external and always global
in scope. Pre-labels affect label localization and must go through
the usual remapping to handle clashes with opcode mnemonics and the
use of leading underscores. Cross-references are computed, but are
associated with the file offset rather than the label line itself.
Added a new filter to the Symbols window ("PreL").
Implemented label input and checking in the address editor. Generally
added highlighting of relevant error labels.
Implemented "is relative" flag. This only affects source code
generation, replacing ".arstart <addr>" with ".arstart *+<value>".
Only output by 64tass and ACME generators.
Added a bold-text summary to radio buttons in address region edit
dialog. This makes it much easier to see what you're doing. Added
a warning to the label edit dialog when a label is being placed in
a non-addressable region.
Modified double-click behavior for .arstart/.arend to jump to the
other end when the opcode is clicked on. This matches the behavior
of instructions with address operands.
Reordered Actions menu, putting "edit operand" at the top.
Fixed AddressMap entry collision testing.
Fixed PRG issue with multiple address regions at offset +000002.
Added regression tests. Most of the complicated stuff with regions
is tested by unit tests inside AddressMap, but we still need to
exercise nested region code generation.
Added support for non-addressable regions, which are useful for things
like file headers stripped out by the system loader, or chunks that
get loaded into non-addressable graphics RAM. Regions are specified
with the "NA" address value. The code list displays the address field
greyed out, starting from zero (which is kind of handy if you want to
know the relative offset within the region).
Putting labels in non-addressable regions doesn't make sense, but
symbol resolution is complicated enough that we really only have two
options: ignore the labels entirely, or allow them but warn of their
presence. The problem isn't so much the label, which you could
legitimately want to access from an extension script, but rather the
references to them from code or data. So we keep the label and add a
warning to the Messages list when we see a reference.
Moved NON_ADDR constants to Address class. AddressMap now has a copy.
This is awkward because Asm65 and CommonUtil don't share.
Updated the asm code generators to understand NON_ADDR, and reworked
the API so that Merlin and cc65 output is correct for nested regions.
Address region changes are now noted in the anattribs array, which
makes certain operations faster than checking the address map. It
also fixes a failure to recognize mid-instruction region changes in
the code analyzer.
Tweaked handling of synthetic regions, which are non-addressable areas
generated by the linear address map traversal to fill in any "holes".
The address region editor now treats attempts to edit them as
creation of a new region.
Updated project file format to save the new map entries.
Tweaked appearance of .arend directives to show the .arstart address
in the operand field. This makes it easier to match them up on screen.
Also, add a synthetic comment on auto-generated .arstart entries.
Added .arstart/.arend to the things that respond to Jump to Operand
(Ctrl+J). Selecting one jumps to the other end. (Well, it jumps
to the code nearest the other, which will do for now.)
Added a menu item to display a text rendering of the address map.
Helpful when things get complicated.
Modified the linear map iterator to return .arend items with the offset
of the last byte in the region, rather than the first byte of the
following region. While the "exclusive end" approach is pretty
common, it caused problems when updating the line list, because it
meant that the .arend directives were outside the range of offsets
being updated (and, for directives at the end of the file, outside
the file itself). This was painful to deal with for partial updates.
Changing this required some relatively subtle changes and annoyed some
of the debug assertions, such as the one where all Line items have
offsets that match the start of a line, but it's the cleaner approach.
Reimplemented "set address" dialog as the Address Region Editor. The
new dialog configures itself differently depending on whether the user
appears to be trying to create, edit, or resize a region. Each mode
has two options, to allow the user to choose between floating and fixed
end points.
The old dialog would allow you to delete an address override by erasing
the address field. Now there's an explicit "delete region" button.
Changed the SetAddress undoable change function to use AddressMapEntry
objects.
We now show detailed information on .arstart/.arend in the Info window
when the lines are selected.
PRG files are now created without specifying a region for the first
two bytes, so the load address exists in a NON_ADDR hole. Fixed a
couple of issues to make that look right.
Split ".org" into ".arstart" and ".arend" (address range start/end).
Address range ends are now shown in the code list view, and the
pseudo-op can be edited in app settings. Address range starts are
now shown after notes and long comments, rather than before, which
brings the on-screen display in sync with generated code.
Reworked the address range editor UI to include the new features.
The implementation is fully broken.
More changes to the AddressMap API, putting the resolved region length
into a separate ActualLength field. Added FindRegion(). Renamed
some things.
Code generation changed slightly: the blank line before a region-end
line now comes after it, and ACME's "} ;!pseudopc" is now just "}".
This required minor updates to some of the regression test results.
This is the first step toward changing the address region map from a
linear list to a hierarchy. See issue #107 for the plan.
The AddressMap class has been rewritten to support the new approach.
The rest of the project has been updated to conform to the new API,
but feature-wise is unchanged. While the map class supports
nested regions with explicit lengths, the rest of the application
still assumes a series of non-overlapping regions with "floating"
lengths.
The Set Address dialog is currently non-functional.
All of the output for cc65 changed because generation of segment
comments has been removed. Some of the output for ACME changed as
well, because we no longer follow "* = addr" with a redundant
pseudopc statement. ACME and 65tass have similar approaches to
placing things in memory, and so now have similar implementations.
If you have a single line selected, Set Address adds a .ORG directive
that changes the addresses of all following data, until the next .ORG
directive is reached. Sometimes code will relocate part of itself,
and it's useful to be able to set the address at the end of the block
to what it would have been before the .ORG change.
If you have multiple lines selected, we now add the second .ORG to
the offset that follows the last selected line.
Also, fixed a bug in the Symbol value updater that wasn't handling
non-unique labels correctly.
Sometimes code relocates a few bits of itself but not others. We
don't currently have a way to say, "go back to where we would have
been". As a cheap alternative, we now show the "load address", i.e.
where we'd be if there were no address map entries after the first.
- 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.