shithub: rgbds

Download patch

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));
 	}