Let RGBASM write JR offsets in floating sections

This requires some special-casing for `jr @` because the `jr` opcode has
already been emitted, but not the operand, so PC points to the middle.
Moved the RGBLINK test to RGBASM's folder, and created a new RGBLINK test.
This commit is contained in:
ISSOtm
2020-07-27 18:11:42 +02:00
parent b1adbcc77c
commit 762474d3ac
13 changed files with 47 additions and 25 deletions

View File

@@ -553,15 +553,21 @@ void out_PCRelByte(struct Expression *expr)
{
checkcodesection();
reserveSpace(1);
struct Symbol const *pc = sym_FindSymbol("@");
if (!rpn_isKnown(expr) || pCurrentSection->nOrg == -1) {
if (!rpn_IsDiffConstant(expr, pc)) {
createPatch(PATCHTYPE_JR, expr);
writebyte(0);
} else {
/* Target is relative to the byte *after* the operand */
uint16_t address = sym_GetPCValue() + 1;
/* The offset wraps (jump from ROM to HRAM, for loopexample) */
int16_t offset = expr->nVal - address;
struct Symbol const *sym = rpn_SymbolOf(expr);
/* The offset wraps (jump from ROM to HRAM, for example) */
int16_t offset;
/* Offset is relative to the byte *after* the operand */
if (sym == pc)
offset = -2; /* PC as operand to `jr` is lower than reference PC by 2 */
else
offset = sym_GetValue(sym) - (sym_GetValue(pc) + 1);
if (offset < -128 || offset > 127) {
yyerror("jr target out of reach (expected -129 < %" PRId16 " < 128)",