1 #include "xc88x.h"
2
3 #include "mdu88x.h"
4
5 static uint16_t v;
6 static uint32_t d;
7
8 /* unsigned OPs */
9
10 uint8_t
mdu_32udiv16(uint32_t op1,uint16_t op2,uint32_t * res,uint16_t * rem)11 mdu_32udiv16(uint32_t op1, uint16_t op2, uint32_t *res, uint16_t *rem)
12 __reentrant
13 {
14 MD0= op1 & 0xff;
15 MD1= (op1 >> 8) & 0xff;
16 MD2= (op1 >> 16) & 0xff;
17 MD3= (op1 >> 24) & 0xff;
18
19 MD4= op2 & 0xff;
20 MD5= (op2 >> 8) & 0xff;
21
22 MDUCON= 0x10 + 0x02;
23 while (MDUSTAT & 0x04) ;
24
25 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
26 if (res)
27 *res= d;
28 v= MD5*256 + MD4;
29 if (rem)
30 *rem= v;
31
32 return MDUSTAT & 0x02;
33 }
34
35 uint8_t
mdu_16udiv16(uint16_t op1,uint16_t op2,uint16_t * res,uint16_t * rem)36 mdu_16udiv16(uint16_t op1, uint16_t op2, uint16_t *res, uint16_t *rem)
37 __reentrant
38 {
39 MD0= op1 & 0xff;
40 MD1= (op1 >> 8) & 0xff;
41 MD4= op2 & 0xff;
42 MD5= (op2 >> 8) & 0xff;
43
44 MDUCON= 0x10 + 0x01;
45 while (MDUSTAT & 0x04) ;
46
47 v= MD1*256 + MD0;
48 if (res)
49 *res= v;
50 v= MD5*256 + MD4;
51 if (rem)
52 *rem= v;
53
54 return MDUSTAT & 0x02;
55 }
56
57 uint8_t
mdu_16umul16(uint16_t op1,uint16_t op2,uint32_t * res)58 mdu_16umul16(uint16_t op1, uint16_t op2, uint32_t *res)
59 __reentrant
60 {
61 MD0= op1 & 0xff;
62 MD4= op2 & 0xff;
63 MD1= (op1 >> 8) & 0xff;
64 MD5= (op2 >> 8) & 0xff;
65
66 MDUCON= 0x10 + 0x00;
67 while (MDUSTAT & 0x04) ;
68
69 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
70 if (res)
71 *res= d;
72
73 return MDUSTAT & 0x02;
74 }
75
76 /* signed OPs */
77
78 uint8_t
mdu_32sdiv16(int32_t op1,int16_t op2,int32_t * res,int16_t * rem)79 mdu_32sdiv16(int32_t op1, int16_t op2, int32_t *res, int16_t *rem)
80 __reentrant
81 {
82 MD0= op1 & 0xff;
83 MD1= (op1 >> 8) & 0xff;
84 MD2= (op1 >> 16) & 0xff;
85 MD3= (op1 >> 24) & 0xff;
86
87 MD4= op2 & 0xff;
88 MD5= (op2 >> 8) & 0xff;
89
90 MDUCON= 0x10 + 0x06;
91 while (MDUSTAT & 0x04) ;
92
93 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
94 if (res)
95 *res= d;
96 v= MD5*256 + MD4;
97 if (rem)
98 *rem= v;
99
100 return MDUSTAT & 0x02;
101 }
102
103 uint8_t
mdu_16sdiv16(int16_t op1,int16_t op2,int16_t * res,int16_t * rem)104 mdu_16sdiv16(int16_t op1, int16_t op2, int16_t *res, int16_t *rem)
105 __reentrant
106 {
107 MD0= op1 & 0xff;
108 MD1= (op1 >> 8) & 0xff;
109 MD4= op2 & 0xff;
110 MD5= (op2 >> 8) & 0xff;
111
112 MDUCON= 0x10 + 0x05;
113 while (MDUSTAT & 0x04) ;
114
115 v= MD1*256 + MD0;
116 if (res)
117 *res= v;
118 v= MD5*256 + MD4;
119 if (rem)
120 *rem= v;
121
122 return MDUSTAT & 0x02;
123 }
124
125 uint8_t
mdu_16smul16(int16_t op1,int16_t op2,int32_t * res)126 mdu_16smul16(int16_t op1, int16_t op2, int32_t *res)
127 __reentrant
128 {
129 MD0= op1 & 0xff;
130 MD4= op2 & 0xff;
131 MD1= (op1 >> 8) & 0xff;
132 MD5= (op2 >> 8) & 0xff;
133
134 MDUCON= 0x10 + 0x04;
135 while (MDUSTAT & 0x04) ;
136
137 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
138 if (res)
139 *res= d;
140
141 return MDUSTAT & 0x02;
142 }
143
144 /* normalize */
145
146 uint8_t
mdu_norm(uint32_t op,uint32_t * res,uint8_t * nuof_shifts)147 mdu_norm(uint32_t op, uint32_t *res, uint8_t *nuof_shifts)
148 __reentrant
149 {
150 MD0= op & 0xff;
151 MD1= (op >> 8) & 0xff;
152 MD2= (op >> 16) & 0xff;
153 MD3= (op >> 24) & 0xff;
154
155 MDUCON= 0x10 + 0x08;
156 while (MDUSTAT & 0x04) ;
157
158 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
159 if (res)
160 *res= d;
161 if (nuof_shifts)
162 *nuof_shifts= MD4 & 0x1f;
163 return MDUSTAT & 0x02;
164 }
165
166 /* logical shifts */
167
168 uint8_t
mdu_lshift(uint32_t op,uint8_t shifts,uint8_t right,uint32_t * res)169 mdu_lshift(uint32_t op, uint8_t shifts, uint8_t right, uint32_t *res)
170 __reentrant
171 {
172 MD0= op & 0xff;
173 MD1= (op >> 8) & 0xff;
174 MD2= (op >> 16) & 0xff;
175 MD3= (op >> 24) & 0xff;
176 MD4= (right?0x20:0) + (shifts&0x1f);
177
178 MDUCON= 0x10 + 0x03;
179 while (MDUSTAT & 0x04) ;
180
181 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
182 if (res)
183 *res= d;
184 return MDUSTAT & 0x02;
185 }
186
187 uint8_t
mdu_lshift_left(uint32_t op,uint8_t shifts,uint32_t * res)188 mdu_lshift_left(uint32_t op, uint8_t shifts, uint32_t *res)
189 __reentrant
190 {
191 return mdu_lshift(op, shifts, 0, res);
192 }
193
194 uint8_t
mdu_lshift_right(uint32_t op,uint8_t shifts,uint32_t * res)195 mdu_lshift_right(uint32_t op, uint8_t shifts, uint32_t *res)
196 __reentrant
197 {
198 return mdu_lshift(op, shifts, 1, res);
199 }
200
201 /* arithmetic shifts */
202
203 uint8_t
mdu_ashift(int32_t op,int8_t shifts,int8_t right,int32_t * res)204 mdu_ashift(int32_t op, int8_t shifts, int8_t right, int32_t *res)
205 __reentrant
206 {
207 MD0= op & 0xff;
208 MD1= (op >> 8) & 0xff;
209 MD2= (op >> 16) & 0xff;
210 MD3= (op >> 24) & 0xff;
211 MD4= (right?0x20:0) + (shifts&0x1f);
212
213 MDUCON= 0x10 + 0x07;
214 while (MDUSTAT & 0x04) ;
215
216 d= (uint32_t)MD0 + (uint32_t)MD1*256l + (uint32_t)MD2*256l*256l + (uint32_t)MD3*256l*256l*256l;
217 if (res)
218 *res= d;
219 return MDUSTAT & 0x02;
220 }
221
222 uint8_t
mdu_ashift_left(int32_t op,int8_t shifts,int32_t * res)223 mdu_ashift_left(int32_t op, int8_t shifts, int32_t *res)
224 __reentrant
225 {
226 return mdu_lshift(op, shifts, 0, res);
227 }
228
229 uint8_t
mdu_ashift_right(int32_t op,int8_t shifts,int32_t * res)230 mdu_ashift_right(int32_t op, int8_t shifts, int32_t *res)
231 __reentrant
232 {
233 return mdu_lshift(op, shifts, 1, res);
234 }
235