6502 Math

From CDOT Wiki
Revision as of 21:48, 14 January 2020 by Chris Tyler (talk | contribs)
Jump to: navigation, search

The 6502 processor is limited to very simple math operations, and various processor flags affect these operations.

Decimal Mode

The 6502 can perform math in binary or decimal mode.

In binary mode, operations are performed on a single 8-bit value. Numbers may be treated as signed or unsigned (the math is the same).

In decimal mode, the each byte is treated as two decimal digits. Numbers are counted as positive.

The rest of this page deals with binary mode (decimal mode operates in mostly the same way).

Addition

The ADC (add with carry) instruction adds together:

the value in the accumulator + the specified byte + the carry flag

If the unsigned value overflows a single byte, the carry flag will be set.

It is therefore important to clear the carry flag (with CLC) before adding the lowest byte of a single or multi-byte value. If a multi-byte addition is performed starting with the lowest byte and proceeding to the highest byte, the carry flag will correctly carry bits forward from one byte to the next. For example, this code adds $30F0 and $0120:

LDA #$F0      ; A=$F0
CLC           ; C=0
ADC #$20      ; Result is $F0+$20+C = $110; therefore A=$10 and C=1
STA LOWBYTE
LDA #$30      ; A=$30
ADC #$01      ; Value is $30+$01+C = $32; therefore A=$32 and C=0
STA HIGHBYTE

The Overflow (V) flag is set if the signed result of the operation is above 127 ($7f) or below -128 ($80).

Subtraction

The SBC (subtract with carry) operation subtracts:

the value in the accumulator - the specified byte - (not Carry)

Where the not operation inverts the value of the carry flag.

The carry flag (which can be viewed as a "borrow" flag for subtraction) is cleared if the result underflows $00 and set otherwise (in other words, if doing unsigned math, the Carry flag is cleared if a bit must be "borrowed").

Normally, you will set the carry flag (with SEC) before performing a subtraction on the lowest byte of a single- or multi-byte subtraction, and then perform subtraction on each byte in sequence up to the highest byte. The borrows will automatically be carried from one byte to the next.

The Overflow (V) flag is set if the signed result of the operation is above 127 ($7f) or below -128 ($80).

Division / LSR

There is no general division operation available. However, Logical Shift Right will effectively perform a division-by-two. A zero will be rotated into the highest bit, and the lowest bit will be shifted into the Carry flag (C).

Multiplication / ASL

There is no general multiplication operation available. However, Arithmetic Shift Left will effectively perform a multiplication-by-two. A zero will be rotated into the lowest bit, and highest bit will be shifted into the Carry flag (C).

Rotate Right/Left

The Rotate Right and Rotate Left (ROR/ROL) instructions are like the LSR/ASL instructions, except that the Carry flag is rotated into one end of the byte, and the bit from the other end is rotated into the Carry flag. For example, ROR will shift C into the high bit and the low bit into C. Therefore, it is possible to perform a multi-byte rotate by stringing together ROR or ROL instructions.