1; 2016 aralbrec
2
3SECTION code_clib
4SECTION code_math
5
6PUBLIC l_z180_mulu_64_64x64
7
8EXTERN l0_z180_mulu_64_32x32
9EXTERN l0_z180_mulu_32_32x32
10
11l_z180_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
32   ld b,(ix+11)
33   ld c,(ix+10)
34
35   ld d,(ix+3)
36   ld e,(ix+2)
37
38   exx
39
40   ld b,(ix+9)
41   ld c,(ix+8)
42
43   ld d,(ix+1)
44   ld e,(ix+0)
45
46   call l0_z180_mulu_64_32x32  ; dehl dehl' = B*D
47
48   exx
49
50   push de
51   push hl                     ; save LS32(B*D)
52
53   ld b,(ix+13)
54   ld c,(ix+12)
55
56   ld d,(ix+1)
57   ld e,(ix+0)
58
59   ld a,b
60   or c
61
62   exx
63
64   ld b,(ix+15)
65   ld c,(ix+14)
66
67   or b
68   or c
69   or (ix+7)
70   or (ix+6)
71   or (ix+5)
72   or (ix+4)
73
74   jr z, finished              ; if multiplicands were 32 bit
75
76   push de
77   push hl                     ; save MS32(B*D)
78
79   ld d,(ix+3)
80   ld e,(ix+2)
81
82   call l0_z180_mulu_32_32x32  ; dehl = LS32(A*D)
83
84   push de
85   push hl                     ; save LS32(A*D)
86
87   ld b,(ix+9)
88   ld c,(ix+8)
89
90   ld d,(ix+5)
91   ld e,(ix+4)
92
93   exx
94
95   ld b,(ix+11)
96   ld c,(ix+10)
97
98   ld d,(ix+7)
99   ld e,(ix+6)
100
101   call l0_z180_mulu_32_32x32  ; dehl = LS32(B*C)
102
103   pop bc
104   add hl,bc
105   ex de,hl
106   pop bc
107   adc hl,bc
108   ex de,hl
109
110   ; dehl = LS32(B*C) + LS32(A*D)
111
112   pop bc
113   add hl,bc
114   ex de,hl
115   pop bc
116   adc hl,bc
117   ex de,hl
118
119finished:
120
121   ; dehl = MS32(product) = LS32(B*C) + LS32(A*D) + MS32(B*D)
122
123   exx
124
125   pop hl
126   pop de
127
128   ; dehl = LS32(product) = LS32(B*D)
129
130   or a
131   ret
132