Adding and subtracting 16 bit values is pretty simple in assembly, I use macros for those.
Here are 16 bit add and subtract macros as examples
Code: Select all
.macro math_ADD_16_16 operand, result
clc
lda result
adc operand
sta result
lda result+1
adc operand+1
sta result+1
.endmacro
.
:
and:
Code: Select all
macro math_SUB_16_16 minuend, result
sec
lda result
sbc minuend
sta result
lda result+1
sbc minuend+1
sta result+1
.endmacro
Individually, they're pretty simple. They're great because they only use one line of assembly code to use, and once debugged, can be assured to work the same again and again.
Multiplication and division use WAY more instructions to implement, but are not complex. The algorithms are the same ones you learned in grade school to multiply and divide, except the "multiplication table" has only one entry instead of 100 for base 10 math.
I have a function that does the multiply, I've never needed to implement a divide. But what I do all the time, is multiple or divide by powers of two... When designing your systems, and they need math, ask yourself "Can I juke this such that it's power of 2 centric?" Because if you can, you can just use a shift algorithm to shift up or down to multiply or divide by a power of 2.
Here's the "shift down 16" macro:
Code: Select all
.macro math_SHIFT_DOWN_16 num_bits, addr16
phx
ldx num_bits
beq :++ ; Do nothing if 0 bits
:
clc
lda addr16+1
ror
sta addr16+1
lda addr16
ror
sta addr16
dex
bne :-
:
plx
.endmacro
I put all of my math macros in a file called "math.inc", it's asm file, "math.asm" has the few routines I use for math.