Carry Flag

From C64-Wiki
Jump to: navigation, search

The Carry Status Flag is a processor status flag, which indicates that an arithmetic carry or borrow has been generated out of the most significant bit position. The carry flag enables numbers larger than a 8 bits to be added/subtracted by carrying (adding) a binary digit from a partial addition/subtraction to the least significant bit position of a more significant byte. It is also used to extend bit shifts and rotates through multiple successive bytes in much the same way.

The following instructions alter the Carry status flag according to the result of their operation: ADC, ASL, CLC, CMP, CPX, CPY, LSR, ROL, ROR, RTI, SBC, and SEC.

The following instructions use the Carry status flag as input to their operation: ADC, BCC, BCS, PHP, ROL, ROR, and SBC.

Branching instructions[edit]

Two branching instructions, are used to perform conditional jumps according to the state of the carry flag:

  • BCC performs the jump only if the Carry status flag is cleared (means unsigned branch on lower for a preceding compare or subtract instruction).
  • BCS performs the jump only if the Carry status flag is set (means unsigned branch on higher or same for a preceding compare or subtract instruction).

Altered by Comparison instructions[edit]

The comparison instructions are implicitly subtractions without altering the value of the accumulator (Carry status flag is initialized automatically). As such, they impact the Negative, Zero and Carry status flags in the same way as the SBC instruction. In terms of the Carry status flag, this behavior becomes important only when comparing multi-byte values. This is done in much the same way that subtraction of multi-byte values, except the results are not stored. Attention has to be payed to the Carry status flag, because each compare instruction initializes it, and therefore has to be especially treated in a multi-byte context. Consequently the condition of the arithmetic flags has to be handled at the end of each comparison.

Suppose you want to compare two, two-byte values stored in zero-page at addresses. The first value is at addresses $2D/$2E and the second value is at addresses $2F/$30. When BASIC is first initialized (or when a CLR statement is executed), these addresses are set to the first byte after the end of the BASIC program and both are the same. When BASIC is first initialized (or when a NEW statement is executed), both contain the two-byte value $0803, the first valid address after the end of BASIC text. The following assembly determines whether these two-byte values are still the same or if they are different (which one is smaller).

                         ; Bytes are operated arithmetically from lowest to highest order
                         ; NumberA is $2D/$2E
                         ; NumberB is $2F/$30
                         ; No need to set the carry flag explicitly, compare
                         ; instructions initialize the flag already.
           LDX $2E       ; Load the high-order byte of NumberA into X
           CPX $30       ; Compare X with the high-order byte of NumberB (A-B)
           BNE CheckSma  ; Between each compare, branch if inequality
           LDX $2D       ; Load the low-order byte of NumberA into X
           CPX $2F       ; Compare X with the low-order byte of NumberB (A-B)
CheckSma   BCC ASmaller  ; Branch if A is smaller than B (unsigned)
           BNE ALarger   ; Since not smaller but not equal either, must be larger
AEqualB    ...           ; This part is executed if A = B
           JMP Done

ALarger:   ...           ; This part is executed if NumberA > NumberB (unsigned)
           JMP Done

ASmaller:  ...           ; This part is executed if NumberA < NumberB (unsigned)
Done: