chk2

Check register against lower and upper bounds 68020

Checks whether a register is within a range defined by two bounds in memory.

Sizes .b .w .l, .w by default68020 only: select opt p=68020 before any code or data

XNZVC –●●●●
  • ● set from the result
  • – not changed

Forms

Operands

<ea>
An operand using one of the addressing modes listed for this form. The list determines whether it can be a register, memory or an immediate value. With opt p=68020, an allowed d(An,Xn) or d(PC,Xn) mode also permits the corresponding 68020 indexed and memory indirect forms. See 68020 addressing. More
Rn
A data or address register, d0 to d7 or a0 to a7. More

The memory operand names two consecutive bounds, lower first, each stored at the instruction’s size. A data register is compared at that size. An address register is compared as a full long, with byte or word bounds sign-extended to long. Both endpoints are included in the range.

Interpret the bounds and value as signed numbers. If the lower bound is at or below the upper bound, the range includes every value between them. If the lower bound is above the upper bound, the range wraps: a value is in range when it is at or above the lower bound, or at or below the upper bound. For example, dc.b 16, 240 stores the signed bounds 16 and -16. Its accepted byte values are 16 through 127 and -128 through -16, which are the unsigned values 16 through 240.

Z is set when the value equals either bound. C is set when it is outside the range. N and V are undefined, and X is unchanged. An out-of-range value raises a CHK exception through vector 6 at $18. The handler returns to the next instruction with rte. Without a handler, the program ends at chk2. See writing a handler. cmp2 performs the same comparison without raising an exception.

opt p=68020
* --- Keep a row number between 1 and 5 ---
move.l #out_of_range, $18 ; vector 6 is at $18
moveq #3, d0
chk2.w rows, d0 ; 3 is between 1 and 5: nothing happens
moveq #9, d0
chk2.w rows, d0 ; 9 is above 5: out_of_range runs
move.w d0, d1 ; rte comes back here: d1 = 5
bra END

out_of_range:
    moveq #5, d0 ; use the last row instead
    rte

rows:
    dc.w 1, 5 ; the lower bound, then the upper one

END: