Kroc Camen<p>Want to share this again because I think it's a work of art; in <a href="https://oldbytes.space/tags/Z80" class="mention hashtag" rel="nofollow noopener" target="_blank">#<span>Z80</span></a> detect if a 16-bit number in HL is outside a signed 8-bit range. "Just check if the hi-byte is non-zero!" you say, but what if the number is negative? -1 ($FFFF) is still the same number when clamped to 8-bits ($FF).</p><p>I like the way the A register is used even though whatever number is in the A register is irrelevant. It could be $00 or $42, the result is the same. We also only branch for errors, not for handling positive vs. negative separately.</p><p>(NB: your client might not render the markdown code included below)</p><p>```<br> sbc HL, BC ; do 'destination - PC'<br> <br> ; check for 8-bit signed bounds:<br> ;-----------------------------------------------------------------------<br> ; the carry-flag indicates if the jump is forward (clear) or backward<br> ; (set). we set A to 0 or -1 ($FF) depending on carry-flag: any value<br> ; minus itself is 0, but the carry-flag is an additional -1 (note that<br> ; the initial value of A is meaningless here, the result is the same)<br> sbc A, A<br> <br> ; detect 8-bit overflow in either direction: if the distance is > 255<br> ; then the hi-byte will not be all 1s (negative) or all 0s (positive)<br> ; therefore we expect A = H. compare sets flags without changing A,<br> ; allowing us to do two tests using the same A value!<br> cp H<br> jp nz, errRangeParam ; err if hi-byte is not 'empty'<br> <br> ; because the relative-distance byte is signed, we expect its sign<br> ; to match that of the result -- a forward jump can only produce<br> ; a positive distance; if the lo-byte is negative it's a positive<br> ; distance that's too large (>127, i.e. hi-bit set)<br> xor L<br> jp m, errRangeParam ; if sign bits differ, error<br> <br> ; output relative-distance byte:<br> ;-----------------------------------------------------------------------<br> ld [IY+0], L ; write relative distance byte<br> inc IY ; move to next byte in code-segment<br> inc IX ; increment virtual program-counter<br> ex DE, HL ; restore heap-addr to HL<br> ret<br>```</p><p><a href="https://oldbytes.space/tags/retrodev" class="mention hashtag" rel="nofollow noopener" target="_blank">#<span>retrodev</span></a> <a href="https://oldbytes.space/tags/retrocomputing" class="mention hashtag" rel="nofollow noopener" target="_blank">#<span>retrocomputing</span></a> <a href="https://oldbytes.space/tags/8bit" class="mention hashtag" rel="nofollow noopener" target="_blank">#<span>8bit</span></a></p>