diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java index 546b32128..31317f191 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/CheckExprSizesVisitor.java @@ -34,6 +34,9 @@ */ public class CheckExprSizesVisitor extends NodeVisitor { private int expectedBytes; + private boolean isRelative; // if we should treat Evaluated value as "relative address" + private int currentAddress; // for computing relative address + @Override public void visit(DataDB node) { @@ -55,8 +58,13 @@ public void visit(DataDS node) { @Override public void visit(Instr node) { - expectedBytes = node.hasRelativeAddress() ? 1 : 0; + boolean oldIsRelative = isRelative; + isRelative = node.hasRelativeAddress(); + currentAddress = node.getAddress(); + + expectedBytes = isRelative ? 1 : 0; visitChildren(node); + isRelative = oldIsRelative; } @Override @@ -96,7 +104,12 @@ public void visit(PseudoMacroArgument node) { @Override public void visit(Evaluated node) { - int value = node.value < 0 ? ((~node.value) * 2) : node.value; + int value; + if (isRelative && node.isAddress) { + value = (node.value - currentAddress - 2); + } else { + value = node.value < 0 ? ((~node.value) * 2) : node.value; + } if (expectedBytes > 0) { int wasBits = (int) Math.floor(Math.log10(Math.abs(value)) / Math.log10(2)) + 1; int wasBytes = (int) Math.ceil(wasBits / 8.0); diff --git a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java index 000ab3b0f..ddc068659 100644 --- a/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java +++ b/plugins/compiler/as-z80/src/main/java/net/emustudio/plugins/compiler/asZ80/visitors/GenerateCodeVisitor.java @@ -68,6 +68,7 @@ public void visit(DataDS node) { @Override public void visit(Instr node) { + boolean oldIsRelative = isRelative; isRelative = node.hasRelativeAddress(); currentAddress = node.getAddress(); @@ -77,7 +78,7 @@ public void visit(Instr node) { expectedBytes = 0; visitChildren(node); } - isRelative = false; + isRelative = oldIsRelative; } @Override diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java index 4ada6e13d..c67fc16e1 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/AbstractCompilerTest.java @@ -114,4 +114,19 @@ protected void assertProgram(int... bytes) { ); } } + + protected void assertProgramWithStart(int startAddress, int... bytes) { + for (int i = 0; i < bytes.length; i++) { + assertEquals( + String.format("[addr=%x] expected=%x, but was=%x", startAddress + i, bytes[i], memoryStub.read(startAddress + i)), + (byte) bytes[i], memoryStub.read(startAddress + i).byteValue() + ); + } + for (int i = bytes.length + startAddress; i < memoryStub.getSize(); i++) { + assertEquals( + String.format("[addr=%x] expected=%x, but was=%x", i, 0, memoryStub.read(i)), + 0, memoryStub.read(i).byteValue() + ); + } + } } diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java index 81183398c..d0f802017 100644 --- a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/IfNodeTest.java @@ -23,7 +23,7 @@ public class IfNodeTest extends AbstractCompilerTest { @Test - public void testIfNodeIsProcessed() throws Exception { + public void testIfNodeIsProcessed() { compile( "if 1\n" + " rrca\n" @@ -36,7 +36,7 @@ public void testIfNodeIsProcessed() throws Exception { } @Test - public void testIfNodeIsNotProcessed() throws Exception { + public void testIfNodeIsNotProcessed() { compile( "if 0\n" + " rrca\n" @@ -47,7 +47,7 @@ public void testIfNodeIsNotProcessed() throws Exception { } @Test - public void testIfNoteIsProcessedForNegativeExpression() throws Exception { + public void testIfNoteIsProcessedForNegativeExpression() { compile( "if -1\n" + " rrca\n" @@ -60,7 +60,7 @@ public void testIfNoteIsProcessedForNegativeExpression() throws Exception { } @Test - public void testIfCanEvaluateBackwardReferenceInExpression() throws Exception { + public void testIfCanEvaluateBackwardReferenceInExpression() { compile( "present equ 1\n" + "if present\n" @@ -74,7 +74,7 @@ public void testIfCanEvaluateBackwardReferenceInExpression() throws Exception { } @Test(expected = Exception.class) - public void testIfCannotRedefineIdentifierInside() throws Exception { + public void testIfCannotRedefineIdentifierInside() { compile( "text: db 6\n" + "if 554\n" diff --git a/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/JumpTest.java b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/JumpTest.java new file mode 100644 index 000000000..eac5582b2 --- /dev/null +++ b/plugins/compiler/as-z80/src/test/java/net/emustudio/plugins/compiler/asZ80/e2e/JumpTest.java @@ -0,0 +1,27 @@ +package net.emustudio.plugins.compiler.asZ80.e2e; + +import org.junit.Test; + +public class JumpTest extends AbstractCompilerTest { + + @Test + public void testDjnzWithLabelOverOneByte() { + String program = "ORG 990\nDL: LD IX,0\n" + + "DJNZ DL\n"; + compile(program); + assertProgramWithStart( + 990, 0xDD, 0x21, 0x00, 0x00, 0x10, -6 + ); + } + + + @Test + public void testJrWithLabelOverOneByte() { + String program = "ORG 990\nDL: LD IX,0\n" + + "jr DL\n"; + compile(program); + assertProgramWithStart( + 990, 0xDD, 0x21, 0x00, 0x00, 0x18, -6 + ); + } +}