Improve Merlin 32 code generation
Incorrect code was generated for a project that used a non-ZP label to do a ZP access (inadvertently, but it's still valid). The adjustment worked correctly for all other assemblers, but Merlin 32 has a strange relationship with the '<' operator, and the generated code used absolute rather than ZP addressing.
(Generating correct zero-page access instructions has been an ongoing issue; see https://github.com/apple2accumulator/merlin32/issues/16 for examples.)
The necessary fix is to append &$ff to the operand, so that the assembler will realize that the operand is small enough to be a zero-page address. This is rather ugly, so we only want to generate it when absolutely necessary. This turns out to be difficult, because the code that generates operands doesn't have enough context to know whether the opcode is implicitly 8 bits (LDA #<FOO, DFB FOO, etc) or is ambiguous. There is some code to force zero-page addressing for ambiguous operands, but it's only used for single-pass assemblers that don't know the label's value ahead of time. For non-Merlin assemblers, <FOO is unambiguously an 8-bit value, and that's what the code currently assumes for Merlin as well.
The forked version of Merlin, v1.1.10, fixed some of the problem but not for all cases. The 20030-labels-and-symbols test case has had some examples added, but the (zp),y case isn't currently exercised. Having this issue fixed in the "official" version of Merlin would help greatly.
Update: In response to the question "Can you force direct (zero) page addressing?", Olivier ZARDINI wrote, "No because there is nothing in Merlin 16+ to do it. The way to force direct page adresseront is to use address on 1byte". So we will need to generate &$ff.
There are also some weird things happening with JMP/JML that may require Merlin output to deviate from common behavior. See https://github.com/apple2accumulator/merlin32/issues/51.
We now output &$ff suffixes. Correct code is being generated for the problematic situations.
There are some older issues, documented in https://github.com/apple2accumulator/merlin32/issues/8, that required generating raw hex instead of assembly instructions in certain situations. These cropped up again, but the existing brute-force workaround still works. These issues were reportedly addressed in v1.1_forked, but their status in v1.2 is unclear. If they have been fixed, we can change the default behavior, and only generate DFB statements when the configured cross-assembler is older.
(The workaround code is here.)