Unsigned arithmetic

When writing control code that hinges on numbers, we should always strive to have our comparison be with zero; that way, no explicit compare is necessary, and we can branch simply with BEQ/BNE, which test the zero flag. Otherwise, we use CMP. The CMP command subtracts its argument from the accumulator (without borrow), updates the flags, but throws away the result. If the value is equal, the result is zero. (CMP followed by BEQ branches if the argument is equal to the accumulator; this is probably why it's called BEQ and not something like BZS.)

Intuitively, then, to check if the accumulator is less than some value, we CMP against that value and BMI. The BMI command branches based on the Negative Flag, which is equal to the seventh bit of CMP's subtract. That's exactly what we need, for signed arithmetic. However, this produces problems if you're writing a boundary detector on your screen or something and find that 192 < 4. 192 is outside of a signed byte's range, and is interpreted as if it were -64. This will not do for most graphics applications, where your values will be ranging from 0-319 or 0-199 or 0-255.

Instead, we take advantage of the implied subtraction that CMP does. When subtracting, the result's carry bit starts at 1, and gets borrowed from if necessary. Let us consider some four-bit subtractions.

C|3210       C|3210
------       ------
1|1001    9  1|1001    9
 |0100  - 4   |1100  -12
------  ---  ------  ---
1|0101    5  0|1101   -3

The CMP command properly modifies the carry bit to reflect this. When computing A-B, the carry bit is set if A >= B, and it's clear if A < B. Consider the following two code sequences.

    (1)                  (2)
  CMP #$C0            CMP #$C0
  BMI label           BCC label

The code in the first column treats the value in the accumulator as a signed value, and branches if the value is less than -64. (Because of overflow issues, it will actually branch for accumulator values between $40 and $BF, even though it *should* only be doing it for values between $80 and $BF. To see why, compare $40 to $C0 and look at the result.) The second column code treats the accumulator as holding an unsigned value, and branches if the value is less than 192. It will branch for accumulator values $00-$BF.