ref: ea52e4533526600b75bebcc1d02f1254e558951d
parent: 9687e6e1dd071ccceb427cc5d6ac03f2d313e79f
author: ISSOtm <eldredhabert0@gmail.com>
date: Fri Feb 7 08:18:49 EST 2020
Fix `@` The symbol's evaluation by the assembler and linker was very inconsistent
--- a/include/asm/rpn.h
+++ b/include/asm/rpn.h
@@ -23,6 +23,9 @@
uint32_t isReloc;
};
+/* FIXME: Should be defined in `asmy.h`, but impossible with POSIX Yacc */
+extern int32_t nPCOffset;
+
uint32_t rpn_isReloc(const struct Expression *expr);
void rpn_Symbol(struct Expression *expr, char *tzSym);
void rpn_Number(struct Expression *expr, uint32_t i);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1206,37 +1206,7 @@
relocconst : T_ID
{
- /*
- * The value of @ needs to be evaluated by the linker,
- * it can only be calculated by the assembler in very
- * few cases (when the base address of a section is
- * known).
- *
- * '@' is a bit special in that it means different
- * things depending on when it is used:
- *
- * - JR/LD/ADD/etc: It refers to the first byte of the
- * instruction (1 byte offset relative to the value
- * stored in the ROM).
- * - DB/DW/DL: It refers to the address of the value
- * that is being saved (0 byte offset relative to the
- * value stored in the ROM.
- *
- * This offset must be added whenever '@' is added to a
- * RPN expression so that the linker can calculate the
- * correct result of any expression that uses '@'.
- */
- if ((strcmp($1, "@") == 0) && (nPCOffset != 0)) {
- struct Expression sTemp, sOffset;
-
- rpn_Symbol(&sTemp, $1);
-
- rpn_Number(&sOffset, nPCOffset);
-
- rpn_SUB(&$$, &sTemp, &sOffset);
- } else {
- rpn_Symbol(&$$, $1);
- }
+ rpn_Symbol(&$$, $1);
}
| T_NUMBER
{
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -154,6 +154,14 @@
pushbyte(expr, *tzSym++);
pushbyte(expr, 0);
expr->nRPNPatchSize += 5;
+
+ /* RGBLINK assumes PC is at the byte being computed... */
+ if (sym == pPCSymbol && nPCOffset) {
+ struct Expression pc = *expr, offset;
+
+ rpn_Number(&offset, nPCOffset);
+ rpn_SUB(expr, &pc, &offset);
+ }
} else {
rpn_Number(expr, sym_GetConstantValue(tzSym));
}