Difference between revisions of "6502 Math"
Chris Tyler (talk | contribs) (→Decimal Mode) |
Chris Tyler (talk | contribs) (→Bitwise Operations) |
||
(One intermediate revision by the same user not shown) | |||
Line 67: | Line 67: | ||
ASL Arithmetic shift left - bit 7 -> C flag, bits 0:6 -> 1:7, 0 -> bit 0 | ASL Arithmetic shift left - bit 7 -> C flag, bits 0:6 -> 1:7, 0 -> bit 0 | ||
LSR Logical shift right - bit 0 -> C flag, bits 7:1 -> 6:0, 0 -> bit 7 | LSR Logical shift right - bit 0 -> C flag, bits 7:1 -> 6:0, 0 -> bit 7 | ||
− | EOR Exclusive-OR ( | + | EOR Exclusive-OR (sometimes written XOR in other languages) |
ORA OR (accumulator) | ORA OR (accumulator) | ||
AND AND | AND AND | ||
Line 74: | Line 74: | ||
The BIT instruction performs a bitwise AND, sets the Z flag based on the result, and transfers bits 6 and 7 of the operand into the N and V flags. | The BIT instruction performs a bitwise AND, sets the Z flag based on the result, and transfers bits 6 and 7 of the operand into the N and V flags. | ||
+ | |||
+ | == Multiplication and Division == | ||
+ | |||
+ | There are no multiplication or division instructions on the 6502; it is up to the programmer to provide the appropriate logic. |
Latest revision as of 00:54, 18 September 2023
The 6502 processor is limited to very simple math operations, and various processor flags affect these operations.
Contents
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 - the lower 4 bits represent the lower digit, and the upper 4 bits represent the upper digit. Numbers are counted as positive, and values greater than 9 are invalid.
Decimal mode is selected by setting the D (Decimal) flag in the Status Register using the SED
instruction, and binary mode is selected by clearing the D flag using the CLD
instruction.
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.
Bitwise Operations
The 6502 offers a basic set of Bitwise Operations, including:
ROR Rotate right - 9-bit rotate (one byte plus C flag) ROL Rotate left - 9-bit rotate left (one byte plus C flag) ASL Arithmetic shift left - bit 7 -> C flag, bits 0:6 -> 1:7, 0 -> bit 0 LSR Logical shift right - bit 0 -> C flag, bits 7:1 -> 6:0, 0 -> bit 7 EOR Exclusive-OR (sometimes written XOR in other languages) ORA OR (accumulator) AND AND
A NOT operation can be performed using EOR with an immediate value of #$FF, and this can be combined with ORA and AND instructions to build NOR and NAND operations.
The BIT instruction performs a bitwise AND, sets the Z flag based on the result, and transfers bits 6 and 7 of the operand into the N and V flags.
Multiplication and Division
There are no multiplication or division instructions on the 6502; it is up to the programmer to provide the appropriate logic.