aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/words/umslashmod.asm
blob: 6adfbb12f6054a66dee24463cd4f8a34d5d8af72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
; ( ud u2 -- rem quot) 
; Arithmetics
; unsigned division ud / u2 with remainder
VE_UMSLASHMOD:
    .dw $ff06
    .db "um/mod"
    .dw VE_HEAD
    .set VE_HEAD = VE_UMSLASHMOD
XT_UMSLASHMOD:
    .dw PFA_UMSLASHMOD
PFA_UMSLASHMOD:
    movw temp4, tosl

    ld temp2, Y+
    ld temp3, Y+
  
    ld temp0, Y+
    ld temp1, Y+

;; unsigned 32/16 -> 16r16 divide

PFA_UMSLASHMODmod:

  ; set loop counter
    ldi temp6,$10

PFA_UMSLASHMODmod_loop:
    ; shift left, saving high bit
    clr temp7
    lsl temp0
    rol temp1
    rol temp2
    rol temp3
    rol temp7

  ; try subtracting divisor
    cp temp2, temp4
    cpc temp3, temp5
    cpc temp7,zerol

    brcs PFA_UMSLASHMODmod_loop_control

PFA_UMSLASHMODmod_subtract:
    ; dividend is large enough
    ; do the subtraction for real
    ; and set lowest bit
    inc temp0
    sub temp2, temp4
    sbc temp3, temp5

PFA_UMSLASHMODmod_loop_control:
    dec  temp6
    brne PFA_UMSLASHMODmod_loop

PFA_UMSLASHMODmod_done:
    ; put remainder on stack
    st -Y,temp3
    st -Y,temp2

    ; put quotient on stack
    movw tosl, temp0
    jmp_ DO_NEXT