I like to keep it simple for numbers that must be displayed on screen and are not used in complex calculations: each digit is a byte. Additions are performed one byte at a time, and after doing each digit you manually check for overflows (digit > 9) and set the carry so this overflow is carried over to the next digit.

For displaying, you just add each byte to the index of the tile that contains the digit "0", and write the result to the name tables or OAM, depending on whether your score display is drawn as background or sprites.

EDIT: Here's an example of how I would add two 3-digit (i.e. 0 to 999) numbers (

`num1 = num1 + num2`):

**Code:**

clc

lda num1+0

adc num2+0

sta num1+0 ;assume no overflow

sbc #9 ;subtract 10

bcc + ;skip if the result is indeed less than 10

sta num1+0 ;store the corrected result

+ lda num1+1

adc num2+1

sta num1+1 ;assume no overflow

sbc #9 ;subtract 10

bcc + ;skip if the result is indeed less than 10

sta num1+1 ;store the corrected result

+ lda num1+2

adc num2+2

sta num1+2 ;assume no overflow

sbc #9 ;subtract 10

bcc + ;skip if the result is indeed less than 10

sta num1+2 ;store the corrected result

+

You could use a loop instead of unrolling everything like in the example, and/or make a subroutine that uses pointers to access the numbers, so you can use the same routine for numbers anywhere in RAM.

EDIT 2: A generic subroutine could look something like this:

**Code:**

AddDecimal:

ldx #6 ;do 6 digits

ldy #0 ;start with the lowest digit

AddDigit:

lda (Num1), y ;get digit from memory location [Num1+Y]

adc (Num2), y ;add to digit at memory location [Num2+Y]

sta (Num1), y ;assume no overflow

sbc #9 ;subtract 10

bcc + ;skip if the result is indeed less than 10

sta (Num1), y ;store the corrected result

+ iny ;move on to the next digit

dex ;decrement the digit counter

bne AddDigit ;add again if there are digits left

rts ;return