ADC (ADd with Carry)¶
A = A + [operand] + C
ADC performs addition on the accumulator register (A), an operand, and the Carry flag. The result it truncated to 8 bits, and then stored in the accumulator. The Carry flag is set if the unsigned result exceeds $FF (255), otherwise it is cleared.
There is no way to perform addition without including the Carry flag. Therefore, the Carry flag is typically cleared (with CLC) before an addition, unless a multi-byte addition is being performed.
If the Decimal flag is set, the ADC instruction assumes that the values being added are in Binary Coded Decimal (BCD) format.
Addressing Modes¶
Mode |
Syntax |
Bytes |
Cycles |
---|---|---|---|
ADC #const |
|
2 |
|
ADC zp |
|
3 |
|
ADC zp,x |
|
4 |
|
ADC addr |
|
4 |
|
ADC addr,x |
|
4-5 |
|
Absolute+Y |
ADC addr,y |
|
4-5 |
ADC (zp,x) |
|
6 |
|
ADC (zp),y |
|
5-6 |
Flags Affected¶
N (Negative) – Set if the result of the addition has the most significant bit set (i.e., is negative); otherwise, it is cleared.
Z (Zero) – Set if the result of the addition is zero; otherwise, it is cleared.
C (Carry) – Set if the unsigned result of the addition is too large to fit in 8 bits; otherwise, it is cleared.
V (Overflow) – Set if the two values being added have the same sign but the result has the opposite sign; otherwise, it is cleared.
Examples¶
Simple Addition to a Constant¶
LDA #10 ; load A with constant 10
CLC ; clear carry flag
ADC #1 ; A now contains 11
This performs a simple addition of a constant value to the accumulator register (A). Here is a step-by-step breakdown of the code:
LDA #10
– This loads the constant value 10 into the accumulator register.CLC
– This clears the carry flag to ensure that the addition operation is performed without including any carry from a previous operation.ADC #1
– This adds the constant value 1 to the value already in the accumulator. Since the carry flag was cleared in the previous step, the addition will not include any carry from a previous operation. As a result, the accumulator now contains the value 11.
Therefore, this code performs a simple addition of the constant value 1 to the constant value 10, and stores the result (11) in the accumulator register.
16-bit Addition¶
LDA $00 ; read memory $00, store in A
CLC ; clear carry flag
ADC $02 ; read memory $02, add to A
STA $00 ; store A into memory $00
LDA $01 ; load memory $01, store in A
ADC $03 ; read memory $03, add to A (retain carry flag)
STA $01 ; store A into memory $01
This code performs the addition of two 16-bit values stored in little-endian byte order. The values to be added are located at memory addresses $00 and $02 for the low byte, and $01 and $03 for the high byte. The result is stored back to memory locations $00 and $01.
Note that the carry flag is cleared before the low bytes are added, but retained for the high byte addition.
BCD Addition¶
Let’s assume that we want to add two BCD numbers $05 and $16 in decimal mode:
SED ; set decimal mode flag
LDA #$05 ; load the first BCD number into A
ADC #$16 ; add the second BCD number to A
CLD ; clear decimal mode flag
It’s important to note that in decimal mode, the ADC instruction adds two BCD numbers together as if they were decimal digits. In this example, $05 + $16 == $21.
If the result of the addition exceeds $99, the processor sets the carry flag (C) and retains the lower two BCD digits, discarding the carry value.
In architectures with IRQ or NMI interrupts, it may be required to disable interrupts while using Decimal mode, because interrupt routines may expect the Decimal flag to be disabled on entry.