Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The hairy part the 6502 instruction set is Subtract With Carry, and the confusion about how the carry flag works as a result of subtracting or comparing.

SBC is implemented by adding the ones-complement (XOR FF) of the number or register. And the carry flag is backwards compared to other architectures, such as the Z80. On input, Carry Set means that you don't want an additional one subtracted, and Carry Clear means you do want an additional one subtracted. Then on output, Carry Set means that no borrow took place, and Carry Clear means that borrow took place. When borrow takes place, you get an additional one subtracted, and that lets you chain the low bytes up to the high bytes and subtract bigger numbers.

CMP is like SBC, except it always adds the extra one whether your input carry is set or not, making it act like you'd expect comparison to act.



Another way to put it is that in SBC context the carry provides for the bit required to turn ones' complement into two's complement (all bits flipped + 1). If it's clear, we fall short by one (so we remain in ones' complement, missing the "+1" part), which makes for a perfect implementation of a borrow. Since SBC is essentially ADC with the invers of the operand (ones' complement) this applies in general (not just for negative values).

(So, technically, the carry is like a ones' complement / two's complement switch. And this is also all we need to implement a borrow in two's complement math.)


The carry is certainly the most complicated flag on the 6502: https://archive.org/details/carryFlagCheatSheetV1.0


Carry flag meaning "not borrow" is the same as ARM, is it not that "backwards compared to other architectures"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: