diff --git a/src/link/patch.cpp b/src/link/patch.cpp index e16befd6..8a0e43f7 100644 --- a/src/link/patch.cpp +++ b/src/link/patch.cpp @@ -588,12 +588,14 @@ static void applyFilePatches(Section §ion, Section &dataSection) { // Offset is relative to the byte *after* the operand // PC as operand to `jr` is lower than reference PC by 2 uint16_t address = patch.pcSection->org + patch.pcOffset + 2; - int32_t jumpOffset = value - address; + // The truncation of `value - address` is intentional, since + // a low ROM0 address may `jr` to a high HRAM one. + int16_t jumpOffset = value - address; if (jumpOffset < -128 || jumpOffset > 127) { firstErrorAt( patch, - "`JR` target must be between -128 and 127 bytes away, not %" PRId32 + "`JR` target must be between -128 and 127 bytes away, not %" PRId16 "; use `JP` instead", jumpOffset ); diff --git a/test/link/jr-wraparound/a.asm b/test/link/jr-wraparound/a.asm new file mode 100644 index 00000000..796baf67 --- /dev/null +++ b/test/link/jr-wraparound/a.asm @@ -0,0 +1,3 @@ +SECTION "low", ROM0[$0048] +LCDInterrupt: + jr hLCDInterruptHandler diff --git a/test/link/jr-wraparound/b.asm b/test/link/jr-wraparound/b.asm new file mode 100644 index 00000000..df368750 --- /dev/null +++ b/test/link/jr-wraparound/b.asm @@ -0,0 +1,4 @@ +SECTION "high", HRAM[$FFE0] +hLCDInterruptHandler:: +.jp: db ; should be $c3 (jp) +.address: dw diff --git a/test/link/jr-wraparound/ref.out.bin b/test/link/jr-wraparound/ref.out.bin new file mode 100644 index 00000000..801fd75f Binary files /dev/null and b/test/link/jr-wraparound/ref.out.bin differ diff --git a/test/link/jr-wraparound/ref.out.sym b/test/link/jr-wraparound/ref.out.sym new file mode 100644 index 00000000..b63e8648 --- /dev/null +++ b/test/link/jr-wraparound/ref.out.sym @@ -0,0 +1,5 @@ +; File generated by rgblink +00:0048 LCDInterrupt +00:ffe0 hLCDInterruptHandler +00:ffe0 hLCDInterruptHandler.jp +00:ffe1 hLCDInterruptHandler.address diff --git a/test/link/test.sh b/test/link/test.sh index 760b136f..cb30efc3 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -191,6 +191,16 @@ tryDiff "$test"/ref.out.map "$outtemp" tryDiff "$test"/ref.out.sym "$outtemp2" evaluateTest +test="jr-wraparound" +startTest +"$RGBASM" -o "$otemp" "$test"/a.asm +"$RGBASM" -o "$outtemp" "$test"/b.asm +continueTest +rgblinkQuiet -o "$gbtemp" -n "$outtemp2" "$otemp" "$outtemp" +tryCmpRom "$test"/ref.out.bin +tryDiff "$test"/ref.out.sym "$outtemp2" +evaluateTest + test="high-low" startTest "$RGBASM" -o "$otemp" "$test"/a.asm