Given the assumption that 0 < A < modulus and 0 < B < modulus, than the following routine for 6502 (following the suggested algorithm of wizzwizz4) does the job:
MODULUS=201
varA=$FC
varB=$FD
;add two numbers A and B given in memory address
;numbers A and B must be < MODULUS
;returns with the value (A+B) mod MODULUS in Accu
clc
lda varA
adc varB
;we only need this if the added numbers could overflow
.if MODULUS>=128
bcc no_overflow
sbc #MODULUS
rts
.endif
no_overflow:
cmp #MODULUS
bcc exit
sbc #MODULUS ;carry is 1 because of past two lines
exit:
rts
I tested several combinations of modulus, A and B with a BASIC program
10 FORM=5TO255STEP37
20 POKE49160,M:POKE49163,M:POKE49167,M
30 FORA=1TOM-1STEP1+INT(M/37)
40 FORB=4TOM-1STEP1+INT(M/26)
50 POKE252,A:POKE253,B:SYS49152
60 C=PEEK(780)
70 D=A+B:IFD>=MTHEND=D-M
80 IFC<>DTHEN PRINTM;A,B,C,D:END
90 NEXTB,A,M
finding it working in all tested cases.
Shortened version hinted by David:
MODULUS=201
varA=$FC
varB=$FD
;add two numbers A and B given in memory address
;numbers A and B must be < MODULUS
;returns with the value (A+B) mod MODULUS in Accu
clc
lda varA
adc varB
;we only need this if the added numbers could overflow
.if MODULUS>=128
bcs overflow
.endif
cmp #MODULUS
bcc exit
overflow:
sbc #MODULUS ;carry is already set
exit:
rts
Automatic testing program for second version:
10 FORM=5TO255STEP37
20 POKE49160,M:POKE49164,M
30 FORA=1TOM-1STEP1+INT(M/37)
40 FORB=4TOM-1STEP1+INT(M/26)
50 POKE252,A:POKE253,B:SYS49152
60 C=PEEK(780)
70 D=A+B:IFD>=MTHEND=D-M
80 IFC<>DTHEN PRINTM;A,B,C,D:END
90 NEXTB,A,M
Some example testcases for manual testing:
A=0, B=0 -> (A+B)%201=0
A=1, B=1 -> (A+B)%201=2
A=100, B=100 -> (A+B)%201=200
A=101, B=100 -> (A+B)%201=0
A=200, B=0 -> (A+B)%201=200
A=200, B=1 -> (A+B)%201=0
A=200, B=200 -> (A+B)%201=199
x
is larger than the modulus in the first place?x
andy
are guaranteed to be belowmodulus
--- that's guaranteed by the nature of modulus arithmetic; I should have made that clearer.