stardot / beebasm

A portable 6502 assembler with BBC Micro style syntax
http://www.retrosoftware.co.uk/wiki/index.php/BeebAsm
GNU General Public License v3.0
83 stars 26 forks source link

New COPYBLOCK error in 1.10rc1, issue not present in 1.09 #75

Closed markmoxon closed 1 year ago

markmoxon commented 1 year ago

The COPYBLOCK directive is producing a fatal error in 1.10rc1 that doesn't occur in 1.09. This is breaking the build of my Revs project.

Here is a minimal test case that demonstrates the issue:

ORG &1200

 LDA #0

ORG &7900

 NOP

COPYBLOCK &7900, &7902, &1200

Save this file as error.asm and try building it. It builds fine in 1.09, but 1.10rc1 fails with this error:

% beebasm -i error.asm
error.asm:3: error: Assembled object code has changed between 1st and 2nd pass. Has a zero-page symbol been forward-declared?

 LDA #0
       ^

The issue seems to be related to the LDA instruction being a two-byte instruction, while the NOP is a one-byte instruction. Replacing LDA #0 with NOP or NOP:NOP removes the error. Similarly, replacing the NOP with LDA #0 also removes the error.

I'm guessing that the COPYBLOCK is copying a one-byte instruction (NOP) over the top of a two-byte instruction (LDA #0), and that mismatch is causing an error?

Revs splits its binary into numerous chunks that are reassembled like a jigsaw when the binary loads, so the project is particularly heavy on the COPYBLOCKs. I can probably move the binary splits into a separate file to get around this, but it's so much clearer to have it all in one file, if possible.

All my other projects assemble fine, but they don't jump through the crazy hoops that Revs does!

Mark

mungre commented 1 year ago

Thank you!

On the second pass beebasm checks that any opcodes assembled to memory match the existing memory contents. The idea is to quickly identify any operands changing in size, which will result in the code shifting so it doesn't match the previous pass.

Previously, beebasm ignored COPYBLOCK on the first pass. In 54bbcd232bb82b77a6758ecf3b02b4338a7f5c2c I changed this so it ran on both passes. This flags the source memory as available for reuse without an explicit CLEAR, but you've found that this breaks the opcode check.

Copying only the flags on the first pass isn't the answer either; this will still mess up the opcode checks in the destination.

Just marking the source memory as unused also won't work especially well; this will allow new code to be assembled there, breaking the opcode checks in the source. Alternatively, the source memory could also be marked as DONT_CHECK (like CLEAR does) but this will automatically prevent opcode checking even in cases where it would have been useful.

I think that the only thing that can be done on the first pass with no downsides is to automatically mark the destination as used to prevent inadvertent overwriting.

To reuse the source memory of a COPYBLOCK you will have to explicitly CLEAR it, like in previous versions.

I'll get that done this evening.

mungre commented 1 year ago

The fix is on the proposed-updates branch. I've tried building the revs disks. They all come out exactly the same exact for revs-plus.ssd. At a quick glance, the credits file with a link back to your site has unix rather than windows line endings, so I guess that's nothing important.

markmoxon commented 1 year ago

Thank you! That's fixed the problem. Great stuff.

(I suspect the line endings issue is something to do with git; I'll take a look, but it's definitely nothing to do with COPYBLOCK.)

mungre commented 1 year ago

Just to confirm, I was using linux when I got the unix line endings.

markmoxon commented 1 year ago

Thank you for confirming. Looks like I've managed to mangle the line endings in the credits file at some point, so it's something to fix at my end - probably a text editor being over-helpful, rather than git. Easy to fix, anyway; thanks for letting me know!

chriskillpack commented 1 year ago

Thanks for fixing this @mungre. IMO this fix is worthy of another release candidate.

mungre commented 1 year ago

Yes, that would be sensible.