Dealing with a circular pattern in the computed mark address.

This commit is contained in:
Rob Greene 2018-07-14 16:47:16 -05:00
parent 87c5930b0c
commit fde074ccdc

View File

@ -1,5 +1,7 @@
package io.github.applecommander.bastools.api.code; package io.github.applecommander.bastools.api.code;
import java.util.HashMap;
/** /**
* A {@code CodeMark} marks a dynamic address within the output stream. When referenced, it will report the * A {@code CodeMark} marks a dynamic address within the output stream. When referenced, it will report the
* most recent address is knows, forcing the generation to run multiple times until it "settles". * most recent address is knows, forcing the generation to run multiple times until it "settles".
@ -16,6 +18,8 @@ package io.github.applecommander.bastools.api.code;
* @author rob * @author rob
*/ */
public class CodeMark { public class CodeMark {
private static final int LOOP_MAX = 10;
private HashMap<Integer,Integer> loopCounter = new HashMap<>();
private int address; private int address;
public int getAddress() { public int getAddress() {
@ -28,6 +32,23 @@ public class CodeMark {
*/ */
public boolean update(GeneratorState state) { public boolean update(GeneratorState state) {
int currentAddress = state.currentAddress(); int currentAddress = state.currentAddress();
loopCounter.merge(currentAddress, 1, (a,b) -> a+b);
if (loopCounter.get(currentAddress) > LOOP_MAX) {
StringBuilder sb = new StringBuilder();
sb.append("A circular pattern in a dynamic address was discovered!\n");
sb.append("This usually indicates that an address was computed to be just below a page boundary.\n");
sb.append("For example, the 0x1000 mark. However, code using that address then pushed the\n");
sb.append("address over the 0x1000 mark, but that triggered the address to be recomputed below\n");
sb.append("the 0x1000 mark. Rinse and repeat.\n");
sb.append("\n");
sb.append("For example, shape tables have a POKE 232,255 when the shape table is at 0xFFF, but the\n");
sb.append("address gets recomputed (due to the 3 digit low address) to be 0x1001, which changes the\n");
sb.append("low address byte to be a single digit. This starts the cascade.\n");
sb.append("\n");
sb.append("Generally, stick a little bit of extra code into the program bypasses this issue.\n");
sb.append("(Sorry, there is no elegant solution at this time. Pull requests are welcome!).\n");
throw new IllegalStateException(sb.toString());
}
try { try {
return currentAddress != address; return currentAddress != address;
} finally { } finally {