1; 2016 aralbrec
2
3SECTION code_clib
4SECTION code_math
5
6PUBLIC l_z80n_mulu_64_64x64
7
8EXTERN l0_z80n_mulu_64_32x32
9EXTERN l0_z80n_mulu_32_32x32
10
11l_z80n_mulu_64_64x64:
12
13   ; 64-bit multiplication
14
15   ; enter :      +-------------------------------
16   ;              | +15
17   ;              | ...  multiplicand AB (8 bytes)
18   ;              | + 8
19   ;         ix = |-------------------------------
20   ;              | + 7
21   ;              | ...  multiplicand CD (8 bytes)
22   ;              | + 0
23   ;              +-------------------------------
24   ;
25   ; exit  : ix structure unchanged
26   ;         dehl' dehl = 64-bit product
27   ;         carry reset
28   ;
29   ; uses  : af, bc, de, hl, af', bc', de', hl'
30
31   ld b,(ix+11)
32   ld c,(ix+10)
33
34   ld d,(ix+3)
35   ld e,(ix+2)
36
37   exx
38
39   ld b,(ix+9)
40   ld c,(ix+8)
41
42   ld d,(ix+1)
43   ld e,(ix+0)
44
45   call l0_z80n_mulu_64_32x32  ; dehl dehl' = B*D
46
47   exx
48
49   push de
50   push hl                     ; save LS32(B*D)
51
52   ld b,(ix+13)
53   ld c,(ix+12)
54
55   ld d,(ix+1)
56   ld e,(ix+0)
57
58   ld a,b
59   or c
60
61   exx
62
63   ld b,(ix+15)
64   ld c,(ix+14)
65
66   or b
67   or c
68   or (ix+7)
69   or (ix+6)
70   or (ix+5)
71   or (ix+4)
72
73   jr z, finished              ; if multiplicands were 32 bit
74
75   push de
76   push hl                     ; save MS32(B*D)
77
78   ld d,(ix+3)
79   ld e,(ix+2)
80
81   call l0_z80n_mulu_32_32x32  ; dehl = LS32(A*D)
82
83   push de
84   push hl                     ; save LS32(A*D)
85
86   ld b,(ix+9)
87   ld c,(ix+8)
88
89   ld d,(ix+5)
90   ld e,(ix+4)
91
92   exx
93
94   ld b,(ix+11)
95   ld c,(ix+10)
96
97   ld d,(ix+7)
98   ld e,(ix+6)
99
100   call l0_z80n_mulu_32_32x32  ; dehl = LS32(B*C)
101
102   pop bc
103   add hl,bc
104   ex de,hl
105   pop bc
106   adc hl,bc
107   ex de,hl
108
109   ; dehl = LS32(B*C) + LS32(A*D)
110
111   pop bc
112   add hl,bc
113   ex de,hl
114   pop bc
115   adc hl,bc
116   ex de,hl
117
118finished:
119
120   ; dehl = MS32(product) = LS32(B*C) + LS32(A*D) + MS32(B*D)
121
122   exx
123
124   pop hl
125   pop de
126
127   ; dehl = LS32(product) = LS32(B*D)
128
129   or a
130   ret
131