I'm trying to find a way to replace the missing decimal mode on the 2A03. Currently I handle scores with each of the 6 digits separately, but I figured out that I could pack 2 digits in one byte, so it'd take 3 bytes of RAM instead of 6.

For this, I'd need some system that reliably add 2 packed BCD numbers together, and set the carry if the result is greater than 100, while keeping the low 2 digits correctly. I don't care the results for invalid BCD numbers.

Now the question is, is it more efficient (ROM and Speed wise) to do so ?

1st idea : Do a binary addition, and do a software "decimal adjust"

2nd idea : Handle each digit separatedly :

I think both solutions are somewhat complex and un-elegant.

For this, I'd need some system that reliably add 2 packed BCD numbers together, and set the carry if the result is greater than 100, while keeping the low 2 digits correctly. I don't care the results for invalid BCD numbers.

Now the question is, is it more efficient (ROM and Speed wise) to do so ?

1st idea : Do a binary addition, and do a software "decimal adjust"

**Code:**

lda _packed_bcd1

clc

adc _packed_bcd2

php

sta _packed_result

eor _packed_bcd1

eor _packed_bcd2 ;Check if half-carry was set

and #$10

bne halfcarryset

lda _packed_result

and #$0f ;Check if any non-valid BCD number

cmp #$0a

bcc nohalfcarry

halfcarryset:

lda #$06 ;If any of those was true -> decimal adjust low digit

clc

adc _packed_result

sta _packed_result

bcc nohalfcarry

pla

php

nohalfcarry:

lda _packed_result

plp

bcs carryset ;Check if full carry was set

cmp #$a0 ;Check for invalid high digit

bcc nocarry

carryset:

adc #$60-1 ;If any of those true -> decimal adjust high digit

sta _packed_result

sec

nocarry:

clc

adc _packed_bcd2

php

sta _packed_result

eor _packed_bcd1

eor _packed_bcd2 ;Check if half-carry was set

and #$10

bne halfcarryset

lda _packed_result

and #$0f ;Check if any non-valid BCD number

cmp #$0a

bcc nohalfcarry

halfcarryset:

lda #$06 ;If any of those was true -> decimal adjust low digit

clc

adc _packed_result

sta _packed_result

bcc nohalfcarry

pla

php

nohalfcarry:

lda _packed_result

plp

bcs carryset ;Check if full carry was set

cmp #$a0 ;Check for invalid high digit

bcc nocarry

carryset:

adc #$60-1 ;If any of those true -> decimal adjust high digit

sta _packed_result

sec

nocarry:

2nd idea : Handle each digit separatedly :

**Code:**

lda _packed_bcd2

and #$0f

sta _c

lda _packed_bcd1

and #$0f

clc

adc _c

cmp #$0a

bcc nouovfl

sbc #$0a

nouovfl:

sta _packed_result

lda #$00

bcc nodadjust

lda #$0f

nodadjust:

adc _packed_bcd1

and #$f0

adc _packed_bcd2

and #$f0

bcs dovfl

cmp #$a0

bcc nodovfl

dovfl:

sbc #$a0

sec

nodovfl:

ora _packed_result

sta _packed_result

and #$0f

sta _c

lda _packed_bcd1

and #$0f

clc

adc _c

cmp #$0a

bcc nouovfl

sbc #$0a

nouovfl:

sta _packed_result

lda #$00

bcc nodadjust

lda #$0f

nodadjust:

adc _packed_bcd1

and #$f0

adc _packed_bcd2

and #$f0

bcs dovfl

cmp #$a0

bcc nodovfl

dovfl:

sbc #$a0

sec

nodovfl:

ora _packed_result

sta _packed_result

I think both solutions are somewhat complex and un-elegant.