diff --git a/include/asm/rpn.h b/include/asm/rpn.h index 24fed5cb..8ee9e3f1 100644 --- a/include/asm/rpn.h +++ b/include/asm/rpn.h @@ -23,6 +23,9 @@ struct Expression { 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); diff --git a/src/asm/asmy.y b/src/asm/asmy.y index ea144b89..13f2e525 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -1206,37 +1206,7 @@ const_16bit : relocconst 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 { diff --git a/src/asm/rpn.c b/src/asm/rpn.c index 8adff069..53e31956 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -154,6 +154,14 @@ void rpn_Symbol(struct Expression *expr, char *tzSym) 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)); }