How about this for 16-bit + signed 8-bit:
Code: Select all
lda delta
bpl pos
dec high
pos: clc
adc low
sta low
bcs noc
inc high
noc:
Heh, and tepples suggested the same thing:
tepples wrote:Perhaps a more efficient way is to decrement the high byte of the sum if the sign bit of the 8-bit value is true: BPL over a DEC.
Another question is raised as well: how to efficiently clamp addition of a signed 8- or 16-bit value to an unsigned 8- or 16-bit value so that adding a positive value doesn't cause the 16-bit value to exceed 65535 and adding a negative value doesn't cause the 16-bit value to fall below 0.
8-bit signed + 8-bit unsigned, clamped to 8-bit unsigned:
Code: Select all
clc
lda signed
bpl pos
neg: adc unsigned
bcs done
lda #0
beq done
pos: adc unsigned
bcc done
lda #$ff
done: sta unsigned
Test output
signed
unsigned
unsigned out
00 00 00
FF 00 00
FF 01 00
80 00 00
80 80 00
80 81 01
7F 80 FF
7F 81 FF
7F FF FF
8-bit signed + 16-bit unsigned, clamped to 16-bit unsigned:
Code: Select all
lda unsigned_lo
clc
adc signed
sta unsigned_lo
lda unsigned_hi
bit signed
bpl pos
neg: adc #$ff
bcs done
lda #0
beq clamp
pos: adc #0
bcc done
lda #$ff
clamp: sta unsigned_lo
done: sta unsigned_hi
Test output
signed
unsigned
unsigned out
00 0000 0000
00 0100 0100
FF 0000 0000
FF 0001 0000
FF 0100 00FF
80 0080 0000
80 0100 0080
01 00FF 0100
01 FFFF FFFF
7F FF81 FFFF
16-bit signed + 16-bit unsigned, clamped to 16-bit unsigned:
Code: Select all
lda unsigned_lo
clc
adc signed_lo
sta unsigned_lo
lda signed_hi
bpl pos
neg: adc unsigned_hi
bcs done
lda #0
beq clamp
pos: adc unsigned_hi
bcc done
lda #$ff
clamp: sta unsigned_lo
done: sta unsigned_hi
Test output
signed
unsigned
unsigned out
0000 0000 0000
7FFF 8000 FFFF
7FFF 8001 FFFF
7FFF FFFF FFFF
8000 0000 0000
8000 7FFF 0000
8000 8000 0000
8000 8001 0001
8000 FFFF 7FFF