1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-12-12 21:29:30 +00:00
Commit Graph

67 Commits

Author SHA1 Message Date
Andy McFadden
0bbb307d4e Correct handling of no-op .ORG statements
These were being overlooked because they didn't actually cause
anything to happen (a no-op .ORG sets the address to what it would
already have been).  The assembly source generator works in a way
that causes them to be skipped, so everybody was happy.

This seemed like the sort of thing that was likely to cause problems
down the road, however, so we now split regions correctly when a
no-op .ORG is encountered.  This affects the uncategorized data
analyzer and selection grouping.

This changed the behavior of the 2004-numeric-types test, which was
visibly weird in the UI but generated correct output.

Added the 2024-ui-edge-cases test to provide a place to exercise
edge cases when testing the UI by hand.  It has some value for the
automated regression test, so it's included there.

Also, changed the AddressMapEntry objects to be immutable.  This
is handy when passing lists of them around.
2020-02-28 14:49:18 -08:00
Andy McFadden
5b75ae35fc Fix ANDImm flag updater
For nonzero values we were leaving Z=prev, which is wrong when Z=0
because the AND result might be zero.  Now if Z=1 we leave it alone,
but if Z=0 we now set it to Z=?.

Test 1003-flags-and-branches was testing for the (incorrect)
behavior, so we're now running into a BRK.  This is fine.
2020-02-01 16:41:44 -08:00
Andy McFadden
c535201884 Prefer narrower project/platform symbols
We want to be able to declare a symbol for a struct or buffer that
spans the entire width, and then declare more-specific items within
it that take precedence.  This worked for everything but the very
first byte, because on an exact match we were resolving the conflict
alphabetically.

Now, if one is wider than the other, we use the narrower definition.

Updated 2021-external-symbols with some additional test cases.
2020-01-23 10:49:22 -08:00
Andy McFadden
da5833caef Rename project/platform symbols that clash with opcode mnemonics
We're doing this for user labels but not for project/platform
symbols.  So if you have a constant named "BCC" you can't assemble
your code with certain assemblers.  Now we rename it automatically.

Added a quick test to 2007-labels-and-symbols.  (No change to ACME,
which barfs on the test.)
2020-01-17 18:29:20 -08:00
Andy McFadden
b387298685 Fix various local variable de-duplication bugs
In 1.5.0-dev1, as part of changes to the way label localization
works, the local variable de-duplicator started checking against a
filtered copy of the symbol table.  Unfortunately it never
re-generated the table, so a long-lived LocalVariableLookup (like
the one used by LineListGen) would set up the dup map wrong and
be inconsistent with other parts of the program.

We now regenerate the table on every Reset().

The de-duplication stuff also had problems when opcodes and
operands were double-clicked on.  When the opcode is clicked, the
selection should jump to the appropriate variable declaration, but
it wasn't being found because the label generated in the list was
in its original form.  Fixed.

When an instruction operand is double-clicked, the instruction operand
editor opens with an "edit variable" shortcut.  This was showing
the de-duplicated name, which isn't necessarily a bad thing, but it
was passing that value on to the DefSymbol editor, which thought it
was being asked to create a new entry.  Fixed.  (Entering the editor
through the LvTable editor works correctly, with nary a de-duplicated
name in sight.  You'll be forced to rename it because it'll fail the
uniqueness test.)

References to de-duplicated local variables were getting lost when
the symbol's label was replaced (due largely to a convenient but
flawed shortcut: xrefs are attached to DefSymbol objects).  Fixed by
linking the XrefSets.

Given the many issues and their relative subtlety, I decided to make
the modified names more obvious, and went back to the "_DUPn" naming
strategy.  (I'm also considering just making it an error and
discarding conflicting entries during analysis... this is much more
complicated than I expected it to be.)

Quick tests can be performed in 2019-local-variables:
 - go to +000026, double-click on the opcode, confirm sel change
 - go to +000026, double-click on the operand, confirm orig name
   shown in shortcut and that shortcut opens editor with orig name
 - go to +00001a, down a line, click on PROJ_ZERO_DUP1 and confirm
   that it has a single reference (from +000026)
 - double-click on var table and confirm editing entry
2020-01-13 18:32:56 -08:00
Andy McFadden
422af1193c Tweak def symbol sort order
The list of EQUs at the top of the file is sorted, by type, then
value, then name.  This adds width as an additional check, so that
if you have overlapping items the widest comes first.

This is nice when you have a general entry for a block of data, and
then specific entries for some locations within the block.
2020-01-04 16:56:31 -08:00
Andy McFadden
5548469ba1 Show large adjustments in hex
We emit address adjustments like "LDA thing+1", which are usually
small values.  Sometimes they're large, e.g. "LDA thing-61440",
which is harder to understand than "LDA thing-$F000".  So now we
show small adjustments in decimal, and large adjustments in hex.

The current definition of "small" is abs(adjust) < 256.
2020-01-02 13:09:18 -08:00
Andy McFadden
32d6d849ea Tweak Merlin DS output
The default fill value is $00.  Don't specify it explicitly when we
don't have to.
2020-01-01 17:45:32 -08:00
Andy McFadden
f157fbbfd3 Add regression test for data analysis bug
The uncategorized data scanner isn't supposed to create strings or
".fill" directives that straddle labels, long comments, notes,
visualizations, or ORG directives.  The test for crossing an ORG
directive is incomplete, and doesn't correctly handle no-op ORGs
(where the new address is the same as the old address).

The code generator doesn't output ORGs that are hidden inside other
things, so we're not generating bad code, but it looks funny on
screen and may cause problems later on.  The 2004-numeric-types test
has the basic .align/.fill/.bulk directive tests, and now has an
extended set of tests for uncategorized data region splitting.
2019-12-30 14:09:18 -08:00
Andy McFadden
bef664ae7e Don't do nearby SYM-1 for zero-page values
It's pretty common for code to access BUFFER-1,X, but it's rare for
the buffer to live on zero page memory.  More often than not we're
auto-formatting zero-page operands with a nearby symbol when they're
just simple variables.  It's more confusing than useful, so we don't
do that anymore.
2019-11-23 16:27:06 -08:00
Andy McFadden
d3670c48e8 Label rework, part 6
Correct handling of local variables.  We now correctly uniquify them
with regard to non-unique labels.  Because local vars can effectively
have global scope we mostly want to treat them as global, but they're
uniquified relative to other globals very late in the process, so we
can't just throw them in the symbol table and be done.  Fortunately
local variables exist in a separate namespace, so we just need to
uniquify the variables relative to the post-localization symbol table.
In other words, we take the symbol table, apply the label map, and
rename any variable that clashes.

This also fixes an older problem where we weren't masking the
leading '_' on variable labels when generating 64tass output.

The code list now makes non-unique labels obvious, but you can't tell
the difference between unique global and unique local.  What's more,
the default type value in Edit Label is now adjusted to Global for
unique locals that were auto-generated.  To make it a bit easier to
figure out what's what, the Info panel now has a "label type" line
that reports the type.

The 2023-non-unique-labels test had some additional tests added to
exercise conflicts with local variables.  The 2019-local-variables
test output changed slightly because the de-duplicated variable
naming convention was simplified.
2019-11-18 13:36:53 -08:00
Andy McFadden
88c56616f7 Label rework, part 5
Implemented assembly source generation of non-unique local labels.
The new 2023-non-unique-labels test exercises various edge cases
(though we're still missing local variable interaction).

The format of uniquified labels changed slightly, so the expected
output of 2012-label-localizer needed to be updated.

This changes the "no opcode mnemonics" and "mask leading underscores"
functions into integrated parts of the label localization process.
2019-11-17 16:05:51 -08:00
Andy McFadden
4e08810278 Finish removal of "disable label localizer" feature
The label localizer is now always on.  The regression tests turned
it off by default, but that's no longer allowed, so the generated
output has changed for many of them.  The tests themselves were not
altered.
2019-11-16 17:15:03 -08:00
Andy McFadden
0a0208409a Tweak line folding code
Some style guides say you should only put one space between
sentences, but I and many others still put two.  The line-folding
code was only eating one of them when they straddled the end of the
line, which looked a little funny because the following line was
indented by one space.

This tweaks the code to eat both spaces.  Regression test updated.

Also, nudge some UI elements so they line up.
2019-11-01 19:47:56 -07:00
Andy McFadden
51081c5db0 Tweak "nearby" label finder
The code that found a nearby data target for an instruction operand
was searching backward but not forward.  We now take one step
forward, so that "LDA TABLE-1,Y" fills in automatically.

This altered 2008-address-changes, which had just this situation.
It didn't alter 2010-target-adjustment, but the existing tests were
insufficient and have been improved.
2019-10-29 18:12:22 -07:00
Andy McFadden
9d5f8f8049 Add a blank line between constants and addresses
In the assembler output, add a blank line between the constants
and addresses in the long list of equates.

The earlier change that corrected the BIT instruction caused test
2009-branches-and-banks to fail, because it was relying on the idea
that BIT made the carry flag indeterminate.  Changing a BCC to a
BVS restored the desired behavior.
2019-10-22 22:45:13 -07:00
Andy McFadden
b6e571afc2 Correctly handle embedded instruction edge case
This began with a change to support "BRK <operand>" in cc65.  The
assembler only supports this for 65816 projects, so we detect that
and enable it when available.

While fiddling with some test code an assertion fired.  This
revealed a minor issue in the code analyzer: when overwriting inline
data with instructions, we weren't resetting the format descriptor.

The code that exercises it, which requires two-byte BRKs and an
inline BRK handler in an extension script, has been added to test
2022-extension-scripts.

The new regression test revealed a flaw in the 64tass code
generator's character encoding scanner that caused it to hang.
Fixed.
2019-10-19 17:28:45 -07:00
Andy McFadden
cd23580cc5 Add junk/align directives
Sometimes there's a bunch of junk in the binary that isn't used for
anything.  Often it's there to make things line up at the start of
a page boundary.

This adds a ".junk" directive that tells the disassembler that it
can safely disregard the contents of a region.  If the region ends
on a power-of-two boundary, an alignment value can be specified.

The assembly source generators will output an alignment directive
when possible, a .fill directive when appropriate, and a .dense
directive when all else fails.  Because we're required to regenerate
the original data file, it's not always possible to avoid generating
a hex dump.
2019-10-18 21:00:28 -07:00
Andy McFadden
bd11aea4a4 External symbol I/O direction and address mask, part 3 (of 3)
Added regression tests.  Improved error messages.  Updated
documentation.
2019-10-16 17:32:30 -07:00
Andy McFadden
6d886ecc3a Change some EQU handling
Changed the sort order on EQU lines so that constants come before
address definitions.  This caused trivial changes to three of the
regression tests.

Added the ability to jump directly to an EQU line when an opcode
is double-clicked on.
2019-10-10 13:49:21 -07:00
Andy McFadden
dfd5bcab1b Optionally treat BRKs as two-byte instructions
Early data sheets listed BRK as one byte, but RTI after a BRK skips
the following byte, effectively making BRK a 2-byte instruction.
Sometimes, such as when diassembling Apple /// SOS code, it's handy
to treat it that way explicitly.

This change makes two-byte BRKs optional, controlled by a checkbox
in the project settings.  In the system definitions it defaults to
true for Apple ///, false for all others.

ACME doesn't allow BRK to have an arg, and cc65 only allows it for
65816 code (?), so it's emitted as a hex blob for those assemblers.
Anyone wishing to target those assemblers should stick to 1-byte mode.

Extension scripts have to switch between formatting one byte of
inline data and formatting an instruction with a one-byte operand.
A helper function has been added to the plugin Util class.

To get some regression test coverage, 2022-extension-scripts has
been configured to use two-byte BRK.

Also, added/corrected some SOS constants.

See also issue #44.
2019-10-09 14:55:56 -07:00
Andy McFadden
dc8e49e4d8 Exercise address-to-offset function in plugin
Also exercise various formatting options.

Also, fix a bug where the code that applies project/platform symbols
to numeric references was ignoring inline data items.
2019-10-07 14:21:26 -07:00
Andy McFadden
28eafef27c Expand the set of things SetInlineDataFormat accepts
Extension scripts (a/k/a "plugins") can now apply any data format
supported by FormatDescriptor to inline data.  In particular, it can
now handle variable-length inline strings.  The code analyzer
verifies the string structure (e.g. null-terminated strings have
exactly one null byte, at the very end).

Added PluginException to carry an exception back to the plugin code,
for occasions when they're doing something so wrong that we just
want to smack them.

Added test 2022-extension-scripts to exercise the feature.
2019-10-05 19:51:34 -07:00
Andy McFadden
37855c8f8e Allow explicit widths in project/platform symbols, part 4 (of 4)
Handle situation where a symbol wraps around a bank.  Updated
2021-external-symbols for that, and to test the behavior when file
data and an external symbol overlap.

The bank-wrap test turned up a bug in Merlin 32.  A workaround has
been added.

Updated documentation to explain widths.
2019-10-03 10:32:54 -07:00
Andy McFadden
0d9814d993 Allow explicit widths in project/platform symbols, part 3
Implement multi-byte project/platform symbols by filling out a table
of addresses.  Each symbol is "painted" into the table, replacing
an existing entry if the new entry has higher priority.  This allows
us to handle overlapping entries, giving boosted priority to platform
symbols that are defined in .sym65 files loaded later.

The bounds on project/platform symbols are now rigidly defined.  If
the "nearby" feature is enabled, references to SYM-1 will be picked
up, but we won't go hunting for SYM+1 unless the symbol is at least
two bytes wide.

The cost of adding a symbol to the symbol table is about the same,
but we don't have a quick way to remove a symbol.

Previously, if two platform symbols had the same value, the symbol
with the alphabetically lowest label would win.  Now, the symbol
defined in the most-recently-loaded file wins.  (If you define two
symbols with the same value in the same file, it's still resolved
alphabetically.)  This allows the user to pick the winner by
arranging the load order of the platform symbol files.

Platform symbols now keep a reference to the file ident of the
symbol file that defined them, so we can show the symbols's source
in the Info panel.

These changes altered the behavior of test 2008-address-changes,
which includes some tests on external addresses that are close to
labeled internal addresses.  The previous behavior essentially
treated user labels as being 3 bytes wide and extending outside the
file bounds, which was mildly convenient on occasion but felt a
little skanky.  (We could do with a way to define external symbols
relative to internal symbols, for things like the source address of
code that gets relocated.)

Also, re-enabled some unit tests.

Also, added a bit of identifying stuff to CrashLog.txt.
2019-10-02 16:50:15 -07:00
Andy McFadden
824add17e8 Remap labels that use opcode mnemonics
In a recent survey, three out of four cross assemblers surveyed
recommended not using opcode mnemonics to their patients who use
labels.  We now remap labels like "AND" and "jmp", using the label
map that's part of the label localizer.

We skip the step for Merlin 32, which is perfectly happy to assemble
"JMP JMP JMP".

Also, fixed a bug in MaskLeadingUnderscores that could hang the
source generator thread.
2019-09-20 15:29:34 -07:00
Andy McFadden
b74630dd5b Work around two assembler issues
Most assemblers end local label scope when a global label is
encountered.  cc65 takes this one step further by ending local label
scope when constants or variables are defined.  So, if we have a
variable table with a nonzero number of entries, we want to create
a fake global label at that point to end the scope.

Merlin 32 won't let you write " LDA #',' ".  For some reason the
comma causes an error.  IGenerator now has a "tweak operand format"
interface that lets us fix that.
2019-09-20 14:05:17 -07:00
Andy McFadden
1ddf4bed48 Fix code tracing bug
If you set things up just right, it's possible for flag status
changes to fail to get merged.

Added a regression test to 1003-flags-and-branches.

Also, tweaked the instruction operand editor to be a bit smoother
from the keyboard: added alt-key shortcuts, and put the focus on the
OK button after creating/editing a label so you can just hit the
return key twice.
2019-09-17 14:38:16 -07:00
Andy McFadden
65fc2cb86e Remove excess whitespace after cycle count comments
If a line has a comment with a cycle count and nothing else, it was
getting an extra space or two on the end.

Also, added a few end-of-line comments to the 2020 test to show how
they interact with the cycle counts.
2019-09-15 17:13:29 -07:00
Andy McFadden
88e72d1eb8 Rename regression test 2020 to reflect the CPU configuration
Cycle counting is CPU-specific.  The 2020 test exercises the
65816, but there are things unique to 6502 and 65C02 that should
also be checked if we want to be thorough.

No changes to the test itself.
2019-09-15 17:02:21 -07:00
Andy McFadden
2828cc8ca7 Apply project/platform symbols to Numeric/Address data operands
A ".dd2 <address>" item would get linked to an internal label, but
references to external addresses weren't doing the appropriate
search through the platform/project symbol list.

This change altered the output of the 2019-local-variables test.
The previous behavior was restored by disabling "nearby" symbol
matching in the project properties.

Updated the "lookup symbol by address" function to ignore local
variables.

Also, minor updates to Applesoft and F8-ROM symbol tables.
2019-09-15 14:38:12 -07:00
Andy McFadden
42e6e6df1e Add 2020-cycle-counts
A quick test to confirm that the cycle counting mechanism is
generating the correct results.
2019-09-14 18:51:03 -07:00
Andy McFadden
62b7655a1c Fix handling of data formatting that overlaps with code
If you play games with code hints you can create a data operand that
overlaps with code.  This causes problems (see issue #45).  We now
check for that situation and ignore overlapping data descriptors.

Added a regression test to 2011-hinting.
2019-09-14 11:44:17 -07:00
Andy McFadden
1631cd77f6 Check both directions for project/platform "nearby" matches
If a symbol is defined at <addr>, and we counter STA <addr>-1,Y,
we want to use the symbol in the operand.  This worked for labels
but not project/platform symbols.

Also, fixed a crash that happened if you tried to delete an auto
label.
2019-09-12 14:24:09 -07:00
Andy McFadden
14b215b76d Implement local variables for cc65
I'd apparently overlooked the ".set" directive, which seems to do
exactly what we need.
2019-09-01 18:14:39 -07:00
Andy McFadden
d542a809f8 Implement local variables for ACME
Unlike 64tass and Merlin, which allow you to redefine symbols, ACME
uses "zones" that provide scope for local variables.  This means
that, at the point of a local variable table definition, we have to
start a new zone and output the full set of active symbols, not just
the newly-defined ones.  (If you set the "clear previous" flag in
the LvTable there's no difference.)

We could do a bit better by only outputting the symbols that are
actually used within the zone, similar to what we do for global
project/platform symbols, but that's a bunch of work for questionable
benefit.
2019-09-01 10:55:19 -07:00
Andy McFadden
c698048001 Handle variable labels that are duplicates of non-variables
After thrashing around a bit, I had to choose between making the
uniquifier more complicated, or making de-duplication a separate
step.  Since I don't really expect duplicates to be a thing, I went
with the latter.

Updated the regression test.
2019-08-31 21:54:20 -07:00
Andy McFadden
963b351a52 Add 2019-local-variables test
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.
2019-08-31 20:40:38 -07:00
Andy McFadden
32d1147eec Improve multi-encoding output in 64tass
Previously, we used the default character encoding from the project
properties to determine how strings and character constants in the
entire source file should be encoded.  Now we switch between
encodings as needed.  The default character encoding is no longer
relevant.

High ASCII is now an actual encoding, rather than acting like ASCII
that sometimes doesn't work.  Because we can do high ASCII character
operands with "| $80", we don't output a .enc to switch from ASCII
to high ASCII unless we need to generate a string.  (If we're
already in high ASCII mode, the "| $80" isn't required but won't
hurt anything.)

We now do a scan up front to see if ASCII or high ASCII is needed,
and only output the .cdefs for the encodings that are actually used.

The only gap in the matrix is high ASCII DCI strings -- the ".shift"
pseudo-op rejects text if the string doesn't start with the high
bit clear.
2019-08-21 13:46:05 -07:00
Andy McFadden
38d3adbb08 PETSCII does DCI
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.
2019-08-20 17:55:12 -07:00
Andy McFadden
149e763821 Change the way ASCII is handled for 64tass
The documentation for 64tass says you're required to pass "--ascii"
when the source file is ASCII (as opposed to PETSCII).  We were
ignoring this, but it turns out that everything works a bit better
if we don't.

So we now pass "--ascii" on the command line, and add a two-line
character encoding definition to every file that is generated with
ASCII as the default encoding.  The sg_petscii and sg_screen
encodings go away, as PETSCII is now the default, and we can use the
built-in "screen" encoding.
2019-08-20 11:21:30 -07:00
Andy McFadden
0abea2beac Update 64tass handling of StackInt ops
The operands for BRK and COP must be expressed as immediate mode
constants, with a leading '#'.
2019-08-19 16:09:11 -07:00
Andy McFadden
037b590967 Improve ACME high ASCII handling
We can !xor a high ASCII string so long as it doesn't include any
escaped characters.
2019-08-17 17:35:01 -07:00
Andy McFadden
479be1a58e Add 2016-char-encoding-a and variations
All tests use the same data file and nearly the same project file.
The only difference is the default text encoding property setting.
For "-a" it's ASCII, for "-p" it's PETSCII, for "-s" it's C64 screen
code.  Right now this only affects the code generated for 64tass.

The test itself is a collection of strings and characters in the
supported character encodings.  How these are handled varies
significantly between assemblers.
2019-08-16 15:01:11 -07:00
Andy McFadden
8fd469b81f Correctly handle delimiters in character operands
We weren't checking to see if character operands matched their
delimiters, so bad code like "LDA #'''" was being generated.

There wasn't a test for this in 2006-operand-formats, so the test
has been updated with single and double quotes in low and high ASCII.
2019-08-14 17:31:15 -07:00
Andy McFadden
f33cd7d8a6 Replace character operand output method
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.
2019-08-11 22:11:00 -07:00
Andy McFadden
a4f5d19295 Improve 64tass output
DCI is handled with the ".shift" pseudo-op.  The .null, .ptext,
and .shift operators all work correctly with escaped characters,
so we no longer redo those.
2019-08-09 19:13:58 -07:00
Andy McFadden
7a40d7f9bf Update expected output for test 2005-string-types
This was the result of the earlier change to eliminate "reverse DCI"
strings.  On further examination, it doesn't seem like we can do
much better than a hex dump without more work than the situation
merits.  So hex dump it is.
2019-08-09 16:41:05 -07:00
Andy McFadden
835c1c7fe2 Reverse position on '#' in block move operands
During a discussion with the cc65 developers, I became convinced that
generating "MVN $01,$02" is wrong, and "MVN #$01,#$02" is correct.
64tass, cc65, and Merlin 32 all accept this syntax; only ACME does
not.  Operands without a leading '#' should be treated as 24-bit
values, and have the bank byte extracted.

This change updates the on-screen display and assembled output to
include the '#'.  The ACME generator uses a Quirk to suppress the
hash mark.  (It doesn't currently accept values larger than 8 bits,
so there's no ambiguity.)
2019-08-08 13:02:01 -07:00
Andy McFadden
a4e90bffd1 Add 2015-64k-nops test
The test file is just 65536 NOPs.
2019-08-04 16:54:01 -07:00