User Tools

Site Tools


addsub

Addition and Subtraction instructions

Simple arithmetic is performed on accumulators with the ADD, SUB, ADC, and SBC instructions. The destination is always the accumulator and the source a memory operand. These instructions are regular across all addressing modes.

To perform addition on the index registers try the LEA instruction.

             adda #20                 ; A takes the value of A+20
             addb #-30                ; add a signed value to B (which likewise is treated as signed)
             subd #$1000              ; 16-bits available for ADD and SUB, but not ADC and SBC
             adcb ,y                  ; indexed addressing
             sbca <reduction          ; direct paged addressing 

ADD

Adds a binary memory operand to an accumulator, A, B, or D. Values can be signed twos complement, or unsigned - it's up to the programmer to be consistent in this regard.

For unsigned values test the Carry flag afterwards; it will be set if there was an overflow from bit 7. For signed values an unintentional overflow from bit 6 will set the Overflow flag. The Zero flag and Negative flag are also set as per the result.

DAA

After an addition of two valid unsigned Binary Coded Decimal bytes the Decimal Add Adjust instruction adjusts the value of A to produce a correct BCD result. A valid BCD byte, when read as a hexadecimal value, is a valid two-digit decimal. For example $42 (normally 66) is actually decimal 42 if we chose it to be a BCD value; and $39+$13=$4C, but is transformed to $52 after DAA.

How does it work? For the 8-bit ADD instruction only, the Half-carry flag is set in the result of a carry from bit 3 to bit 4. This is used together with the Carry as part of an intricate adjustment based on the values of each nybble.

What's the point of BCD? In the early days of calculators the conversion from decimal to binary and back again was far more complex than any arithmetic they were likely to perform. Hence this easy to read and display internal format. Nowadays it is pretty well obsolete.

ADC

Adds a memory operand, together with the Carry to an 8-bit accumulator, A, or B. There is no 16-bit version of this instruction. Multi-byte arithmetic can be performed by looping using ADC to add bytes, including the carry from the previous addition, starting with the least significant byte.

SUB

Subtracts a binary memory operand from an accumulator, A, B, or D. Values can be signed twos complement, or unsigned - it's up to the programmer to be consistent in this regard. Flags are set and tested as per ADD.

SBC

Subtracts a binary memory operand, together with the Carry (sometimes called the Borrow in this context) from an 8-bit accumulator, A, or B. There is no 16-bit version of this instruction.

When the Carry flag is clear this is just like SUB. When the Carry is set a value of 1 is subtracted first, so for example, LDA #10; SBCA #3 loads A with 10-1-3, so A becomes 6. Therefore SBC can be used for multi-precision arithmetic just like ADC.

Examples

Convert a list of bytes representing decimal digits ranging from 0 to 9 to equivalent printable ASCII characters.

             ldb #numDigits
printLoop:   lda, x+
             adda #$30        ; add ASCII '0' to 0..9 range byte for a printable character
             jsr printChar
             decb
             bne printLoop

Multi-precision binary arithmetic. Add the value addressed by Y to that addressed by X. Values are stored in byte big-endian form, so first the number of bytes in the value has to be added to the index register so we can start the addition with the least significant digit. Any carry caused by an addition is added to the next most significant byte.

             ldb #numBytes
             leax numBytes,x
             leay numBytes,y
             andcc #$fe       ; clear Carry flag 
multiByte:   lda ,-y
             adca, -x
             sta ,x
             decb             ; DEC instruction does not alter the Carry flag
             bne multiByte              

Add a bonus to a score. Both are 8-bit signed; overflow is detected and adjusted for before storing the 16-bit total.

             clra
             ldb score
             addb bonus
             bvc standard
overflow:    bmi corrected       ; -$50 + -$32 = $B0 + $CE = $7E+Carry = $FF7E
             coma                ; $50 + $32 = $0082
             bra corrected
standard:    sex                 ; sign extend B into D, which is A(hi):B(lo) 
corrected:   std total                   
addsub.txt · Last modified: 2024/01/26 09:34 by reggie