Skip to content
Game 0 Unit 12 of 16 1 hr learning time

Adding and Taking Away

The most ordinary thing of all, finally: maths. adc and sbc on a value — and the carry flag the 6510 makes you mind: clear it before you add, set it before you subtract.

75% of Meet The Machine

You can move values, compare them, loop, branch, index and call — and yet you've never done the most ordinary thing a program does: arithmetic. Before you build a game, the last pieces of plain fluency. This one is the simplest: LET X = X + 1.

And here the 6510 has a quirk you'll meet on day one and never forget. There's no "add 1 to A" instruction — no inc a at all. Adding to the accumulator goes through one instruction, adcADd with Carry — and the name is a warning: it always adds the carry flag in too. So before the first add you clear the carry yourself:

  • clcCLear the Carry. Do this before you start adding.
  • adc #1 — add 1 (plus the carry, which you just made sure is 0).
  • sec / sbc #1 — to subtract, SEt the Carry first, then SuBtract with Carry.

Forget the clc and your sum comes out one too high; forget the sec and your difference comes out one too low. It catches everyone once. (The index registers have their own steps — inx / dex / iny / dey — and those don't touch carry at all. It's the accumulator that makes you mind it.)

What you'll see by the end

The C64 screen surrounded by a green border.
Green (colour 5) that was never loaded but computed — start at 2, clear the carry, add one three times.

A green border — colour 5. But we never loaded 5; we computed it: start at 2, clear the carry, add one three times. In a real game the numbers are a score or a position you don't know ahead of time. Here they're constants so you can check the sum yourself.

Computing a value

; Meet the Machine - Unit 12: Adding and Taking Away
; Assemble with: acme -f cbm -o maths.prg maths.asm

*= $0801
!byte $0c,$08,$0a,$00,$9e,$32,$30,$36,$31,$00,$00,$00

*= $080d
        lda #2          ; start at 2
        clc             ; clear the carry BEFORE adding
        adc #1          ; 2 + 1 = 3
        adc #1          ; 3 + 1 = 4
        adc #1          ; 4 + 1 = 5
        sta $d020       ; show it — green
loop    jmp loop

2, clc, then adc #1 three times — 3, 4, 5 — and show it. We clear the carry once, up front; after that no add overflows, so the carry stays clear and each adc #1 adds exactly one. Same shape as loading the border, but the value is worked out, not written down. That's the whole difference between a constant and a calculation.

Assemble and run

acme -f cbm -o maths.prg maths.asm

A green border, arrived at by adding.

Try this: past the edge of a byte

Replace the body with lda #255 then clc / adc #1, and watch A in the register view: it reads 0, not 256. A byte can't hold 256, so it wraps to 0 — and the carry flag is set, the machine flagging "that overflowed." A bcs would fire on it. This is how you'd catch a score rolling over — and, next unit but one, how numbers bigger than a byte are built.

Try this: taking away

Subtract with sec / sbc: lda #6, sec, sbc #2 leaves 4 (purple). Forget the sec and you'd get 3 instead — one short, because the missing carry counts as a borrow. And subtracting past zero wraps the other way: lda #0, sec, sbc #1 gives 255, this time clearing the carry (a borrow happened). Predict each before you run it.

If it doesn't work

  • Your sum is one too high. You forgot the clc before the first adc — the leftover carry added an extra 1.
  • Your difference is one too low. You forgot the sec before the first sbc. Subtraction needs the carry set to mean "no borrow."
  • The border colour looks "wrong". It isn't — the border shows only the low four bits, so any result is shown mod 16. Check the register view for the true answer.

What you've learnt

You add with clc / adc and subtract with sec / sbc — the 6510 folds the carry into every one, so you set it up first — and a result past 255 (or below 0) wraps and flips the carry, the machine's overflow signal.

What's next

Sometimes you don't want to change a whole number — just one bit of it. Next — Working With Bitsand, ora and eor let you clear, set and flip individual bits, the everyday way to throw one switch in a byte and leave the other seven alone.