SBC is "Subtract with Carry".
Carry is what we call "Vai um" popularly, in a sum (or "lends one" in a subtraction).
In decimal, follows an example of Carry:
₁ ← carry ₁
17 17 17 somando o Carry
+ 05 → + 05 → + 05 (o 1 que subimos)
———— ———— ———— obtemos o resultado
2 22 correto, que é 22
In binary the logic is the same.
Important: Although I have given an example with the two decimal digits, the complexity of carry is not because of the bits of the same byte. Carry is used to pass bits from one byte to another, for example if you have 0x00 0xff and add one in 0xff, the byte goes back to 0x00 and the carry is set, for later you use the most significant byte, reaching 0x01 0x00 (and so on, if you use more than 8 bits).
Knowing what Carry is, let’s go to what happened in the code:
The first problem is that you don’t know how Carry was at the beginning of the operation. It may be that the processor has noted the "go one" of a previous operation.
The second is that even if it was zeroed, Carry is kind of counterintuitive in subtraction, because it works "upside down".
To solve, we have these two instructions:
CLC
is "Clear Carry"
SEC
is "Set Carry"
If it was an addition, we’d need a CLC
before starting. Since it’s about subtraction, it’s the reverse, we need to "set" the Carry with the SEC
before starting, thus leaving the code:
LDA #$5 ; A=5
SEC ; Setamos o Carry para iniciar.
SBC #$1 ; A=4, como esperado.
SBC #$1 ; A=3, como esperado.
SBC #$1 ; A=2, como esperado.
SBC #$1 ; A=1, como esperado.