annotate src/math.asm @ 243:ee81f46714cb

auto-select correct settings menu
author heinrichsweikamp
date Wed, 04 Mar 2015 16:25:44 +0100 (2015-03-04)
parents 11d4fc797f74
children 653a3ab08062
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
heinrichsweikamp
parents:
diff changeset
1 ;=============================================================================
heinrichsweikamp
parents:
diff changeset
2 ;
heinrichsweikamp
parents:
diff changeset
3 ; File math.asm
heinrichsweikamp
parents:
diff changeset
4 ;
heinrichsweikamp
parents:
diff changeset
5 ; Math subroutines
heinrichsweikamp
parents:
diff changeset
6 ;
heinrichsweikamp
parents:
diff changeset
7 ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved.
heinrichsweikamp
parents:
diff changeset
8 ;=============================================================================
heinrichsweikamp
parents:
diff changeset
9 ; HISTORY
heinrichsweikamp
parents:
diff changeset
10 ; 2011-08-03 : [mH] moving from OSTC code
heinrichsweikamp
parents:
diff changeset
11
heinrichsweikamp
parents:
diff changeset
12
heinrichsweikamp
parents:
diff changeset
13 #include "ostc3.inc" ; Mandatory header
heinrichsweikamp
parents:
diff changeset
14
heinrichsweikamp
parents:
diff changeset
15 basic CODE
heinrichsweikamp
parents:
diff changeset
16 ;=============================================================================
heinrichsweikamp
parents:
diff changeset
17 global convert_time
heinrichsweikamp
parents:
diff changeset
18 convert_time: ; converts hi:lo in minutes to hours (hi) and minutes (lo)
heinrichsweikamp
parents:
diff changeset
19 movff lo,xA+0 ; divide by 60...
heinrichsweikamp
parents:
diff changeset
20 movff hi,xA+1 ;
heinrichsweikamp
parents:
diff changeset
21 movlw d'60' ;
heinrichsweikamp
parents:
diff changeset
22 movwf xB+0 ;
heinrichsweikamp
parents:
diff changeset
23 clrf xB+1 ;
heinrichsweikamp
parents:
diff changeset
24 rcall div16x16 ; xA/xB=xC with xA as remainder
heinrichsweikamp
parents:
diff changeset
25 movff xC+0,hi ; Hours
heinrichsweikamp
parents:
diff changeset
26 movff xA+0,lo ; =remaining minutes (0.....59)
heinrichsweikamp
parents:
diff changeset
27 return
heinrichsweikamp
parents:
diff changeset
28
heinrichsweikamp
parents:
diff changeset
29 global div16
heinrichsweikamp
parents:
diff changeset
30 div16:
heinrichsweikamp
parents:
diff changeset
31 ; divA=divA/2^divB (divB: 8Bit only!)
heinrichsweikamp
parents:
diff changeset
32 bcf STATUS,C
heinrichsweikamp
parents:
diff changeset
33 rrcf divA+1
heinrichsweikamp
parents:
diff changeset
34 rrcf divA+0
heinrichsweikamp
parents:
diff changeset
35 decfsz divB
heinrichsweikamp
parents:
diff changeset
36 bra div16
heinrichsweikamp
parents:
diff changeset
37 return
heinrichsweikamp
parents:
diff changeset
38
heinrichsweikamp
parents:
diff changeset
39 global sub16
heinrichsweikamp
parents:
diff changeset
40 sub16:
heinrichsweikamp
parents:
diff changeset
41 ; sub_c = sub_a - sub_b (with signed values)
heinrichsweikamp
parents:
diff changeset
42 bcf neg_flag
heinrichsweikamp
parents:
diff changeset
43 movf sub_b+0, W ; Get Value to be subtracted
heinrichsweikamp
parents:
diff changeset
44 subwf sub_a+0, W ; Do the High Byte
heinrichsweikamp
parents:
diff changeset
45 movwf sub_c+0
heinrichsweikamp
parents:
diff changeset
46 movf sub_b+1, W ; Get the Value to be Subbed
heinrichsweikamp
parents:
diff changeset
47 subwfb sub_a+1, W
heinrichsweikamp
parents:
diff changeset
48 movwf sub_c+1
heinrichsweikamp
parents:
diff changeset
49
heinrichsweikamp
parents:
diff changeset
50 btfss STATUS,N ; Negativ result ?
heinrichsweikamp
parents:
diff changeset
51 return ; NO: result positive done.
heinrichsweikamp
parents:
diff changeset
52
heinrichsweikamp
parents:
diff changeset
53 bsf neg_flag ; MARK result negative
heinrichsweikamp
parents:
diff changeset
54
heinrichsweikamp
parents:
diff changeset
55 comf sub_c+1 ; 16bit sign change.
heinrichsweikamp
parents:
diff changeset
56 negf sub_c+0
heinrichsweikamp
parents:
diff changeset
57 btfsc STATUS,C ; Carry to propagate ?
heinrichsweikamp
parents:
diff changeset
58 incf sub_c+1,F ; YES: do it.
heinrichsweikamp
parents:
diff changeset
59
heinrichsweikamp
parents:
diff changeset
60 return
heinrichsweikamp
parents:
diff changeset
61
heinrichsweikamp
parents:
diff changeset
62 global subU16
heinrichsweikamp
parents:
diff changeset
63 subU16:
heinrichsweikamp
parents:
diff changeset
64 ; sub_c = sub_a - sub_b (with UNSIGNED values)
heinrichsweikamp
parents:
diff changeset
65 bcf neg_flag
heinrichsweikamp
parents:
diff changeset
66 movf sub_b+0, W ; Get Value to be subtracted
heinrichsweikamp
parents:
diff changeset
67 subwf sub_a+0, W ; Do the High Byte
heinrichsweikamp
parents:
diff changeset
68 movwf sub_c+0
heinrichsweikamp
parents:
diff changeset
69 movf sub_b+1, W ; Get the Value to be Subbed
heinrichsweikamp
parents:
diff changeset
70 subwfb sub_a+1, W
heinrichsweikamp
parents:
diff changeset
71 movwf sub_c+1
heinrichsweikamp
parents:
diff changeset
72 btfsc STATUS,C ; Borrow to propagate ? (B == /CARRY)
heinrichsweikamp
parents:
diff changeset
73 return ; NO: result positive done.
heinrichsweikamp
parents:
diff changeset
74 bsf neg_flag ; MARK result negative
heinrichsweikamp
parents:
diff changeset
75 comf sub_c+1 ; 16bit sign change.
heinrichsweikamp
parents:
diff changeset
76 negf sub_c+0
heinrichsweikamp
parents:
diff changeset
77 btfsc STATUS,C ; Carry to propagate ?
heinrichsweikamp
parents:
diff changeset
78 incf sub_c+1,F ; YES: do it.
heinrichsweikamp
parents:
diff changeset
79 return
heinrichsweikamp
parents:
diff changeset
80
heinrichsweikamp
parents:
diff changeset
81 global mult16x16
heinrichsweikamp
parents:
diff changeset
82 mult16x16: ;xA*xB=xC
heinrichsweikamp
parents:
diff changeset
83 clrf xC+2 ; Clear the High-Order Bits
heinrichsweikamp
parents:
diff changeset
84 clrf xC+3
heinrichsweikamp
parents:
diff changeset
85 movf xA, w ; Do the "L" Multiplication first
heinrichsweikamp
parents:
diff changeset
86 mulwf xB
heinrichsweikamp
parents:
diff changeset
87 movf PRODL, w ; Save result
heinrichsweikamp
parents:
diff changeset
88 movwf xC
heinrichsweikamp
parents:
diff changeset
89 movf PRODH, w
heinrichsweikamp
parents:
diff changeset
90 movwf xC+1
heinrichsweikamp
parents:
diff changeset
91 movf xA, w ; Do the "I" Multiplication
heinrichsweikamp
parents:
diff changeset
92 mulwf xB+1
heinrichsweikamp
parents:
diff changeset
93 movf PRODL, w ; Save the Most Significant Byte First
heinrichsweikamp
parents:
diff changeset
94 addwf xC+1, f
heinrichsweikamp
parents:
diff changeset
95 movf PRODH, w
heinrichsweikamp
parents:
diff changeset
96 addwfc xC+2, f ; Add to the Last Result
heinrichsweikamp
parents:
diff changeset
97 movf xA+1, w ; Do the "O" Multiplication
heinrichsweikamp
parents:
diff changeset
98 mulwf xB
heinrichsweikamp
parents:
diff changeset
99 movf PRODL, w ; Add the Lower Byte Next
heinrichsweikamp
parents:
diff changeset
100 addwf xC+1, f
heinrichsweikamp
parents:
diff changeset
101 movf PRODH, w ; Add the High Byte First
heinrichsweikamp
parents:
diff changeset
102 addwfc xC+2, f
heinrichsweikamp
parents:
diff changeset
103 btfsc STATUS, C ; Add the Carry
heinrichsweikamp
parents:
diff changeset
104 incf xC+3, f
heinrichsweikamp
parents:
diff changeset
105 movf xA+1, w ; Do the "F" Multiplication
heinrichsweikamp
parents:
diff changeset
106 mulwf xB+1
heinrichsweikamp
parents:
diff changeset
107 movf PRODL, w
heinrichsweikamp
parents:
diff changeset
108 addwf xC+2, f
heinrichsweikamp
parents:
diff changeset
109 movf PRODH, w
heinrichsweikamp
parents:
diff changeset
110 addwfc xC+3, f
heinrichsweikamp
parents:
diff changeset
111 return
heinrichsweikamp
parents:
diff changeset
112
heinrichsweikamp
parents:
diff changeset
113 global div16x16
heinrichsweikamp
parents:
diff changeset
114 div16x16: ;xA/xB=xC with xA+0 as remainder
heinrichsweikamp
parents:
diff changeset
115 ;uses divB as temp variable
heinrichsweikamp
parents:
diff changeset
116 clrf xC+0
heinrichsweikamp
parents:
diff changeset
117 clrf xC+1
heinrichsweikamp
parents:
diff changeset
118 MOVF xB+0,W ; Check for zero
heinrichsweikamp
parents:
diff changeset
119 IORWF xB+1,W ;
heinrichsweikamp
parents:
diff changeset
120 BTFSC STATUS,Z ; Check for zero
heinrichsweikamp
parents:
diff changeset
121 RETLW H'FF' ; return 0xFF if illegal
heinrichsweikamp
parents:
diff changeset
122 MOVLW 1 ; Start count at 1
heinrichsweikamp
parents:
diff changeset
123 MOVWF divB ; Clear Count
heinrichsweikamp
parents:
diff changeset
124 div16x16_1:
heinrichsweikamp
parents:
diff changeset
125 BTFSC xB+1,7 ; High bit set ?
heinrichsweikamp
parents:
diff changeset
126 bra div16x16_2 ; Yes then continue
heinrichsweikamp
parents:
diff changeset
127 INCF divB,F ; Increment count
heinrichsweikamp
parents:
diff changeset
128
heinrichsweikamp
parents:
diff changeset
129 bcf STATUS,C
heinrichsweikamp
parents:
diff changeset
130 rlcf xB+0,F
heinrichsweikamp
parents:
diff changeset
131 rlcf xB+1,F
heinrichsweikamp
parents:
diff changeset
132 bra div16x16_1
heinrichsweikamp
parents:
diff changeset
133 div16x16_2:
heinrichsweikamp
parents:
diff changeset
134 ; Shift result left
heinrichsweikamp
parents:
diff changeset
135 bcf STATUS,C
heinrichsweikamp
parents:
diff changeset
136 rlcf xC+0,F
heinrichsweikamp
parents:
diff changeset
137 rlcf xC+1,F
heinrichsweikamp
parents:
diff changeset
138
heinrichsweikamp
parents:
diff changeset
139 ; Reduce Divisor
heinrichsweikamp
parents:
diff changeset
140
heinrichsweikamp
parents:
diff changeset
141 MOVF xB,W ; Get low byte of subtrahend
heinrichsweikamp
parents:
diff changeset
142 SUBWF xA,F ; Subtract DST(low) - SRC(low)
heinrichsweikamp
parents:
diff changeset
143 MOVF xB+1,W ; Now get high byte of subtrahend
heinrichsweikamp
parents:
diff changeset
144 BTFSS STATUS,C ; If there was a borrow, rather than
heinrichsweikamp
parents:
diff changeset
145 INCF xB+1,W ; decrement high byte of dst we inc src
heinrichsweikamp
parents:
diff changeset
146 SUBWF xA+1,F ; Subtract the high byte and we're done
heinrichsweikamp
parents:
diff changeset
147
heinrichsweikamp
parents:
diff changeset
148
heinrichsweikamp
parents:
diff changeset
149 BTFSC STATUS, C ; Did it reduce?
heinrichsweikamp
parents:
diff changeset
150 bra div16x16_3 ; No, so it was less than
heinrichsweikamp
parents:
diff changeset
151
heinrichsweikamp
parents:
diff changeset
152 movf xB+0,W ; Reverse subtraction
heinrichsweikamp
parents:
diff changeset
153 addwf xA+0,F
heinrichsweikamp
parents:
diff changeset
154 movf xB+1,W
heinrichsweikamp
parents:
diff changeset
155 addwfc xA+1,F
heinrichsweikamp
parents:
diff changeset
156
heinrichsweikamp
parents:
diff changeset
157 bra div16x16_4 ; Continue the process
heinrichsweikamp
parents:
diff changeset
158 div16x16_3:
heinrichsweikamp
parents:
diff changeset
159 BSF xC+0,0 ; Yes it did, this gets a 1 bit
heinrichsweikamp
parents:
diff changeset
160 div16x16_4:
heinrichsweikamp
parents:
diff changeset
161 DECF divB,F ; Decrement N_COUNT
heinrichsweikamp
parents:
diff changeset
162 BTFSC STATUS,Z ; If its not zero then continue
heinrichsweikamp
parents:
diff changeset
163 return
heinrichsweikamp
parents:
diff changeset
164
heinrichsweikamp
parents:
diff changeset
165 bcf STATUS,C
heinrichsweikamp
parents:
diff changeset
166 rrcf xB+1,F
heinrichsweikamp
parents:
diff changeset
167 rrcf xB+0,F
heinrichsweikamp
parents:
diff changeset
168
heinrichsweikamp
parents:
diff changeset
169 bra div16x16_2 ; Next bit.
heinrichsweikamp
parents:
diff changeset
170
heinrichsweikamp
parents:
diff changeset
171 global div32x16
heinrichsweikamp
parents:
diff changeset
172 div32x16: ; xC:4 / xB:2 = xC+3:xC+2 with xC+1:xC+0 as remainder
heinrichsweikamp
parents:
diff changeset
173 ; Setup
heinrichsweikamp
parents:
diff changeset
174 movlw .32 ; setup shift counter
heinrichsweikamp
parents:
diff changeset
175 movwf divB
heinrichsweikamp
parents:
diff changeset
176 movff xC+3,xA+1 ; move ACCb to ACCf
heinrichsweikamp
parents:
diff changeset
177 movff xC+2,xA+0
heinrichsweikamp
parents:
diff changeset
178 movff xC+1,sub_a+1 ; move ACCc to ACCe
heinrichsweikamp
parents:
diff changeset
179 movff xC+0,sub_a+0
heinrichsweikamp
parents:
diff changeset
180 clrf xC+3
heinrichsweikamp
parents:
diff changeset
181 clrf xC+2
heinrichsweikamp
parents:
diff changeset
182 clrf xC+1
heinrichsweikamp
parents:
diff changeset
183 clrf xC+0
heinrichsweikamp
parents:
diff changeset
184 clrf sub_b+1
heinrichsweikamp
parents:
diff changeset
185 clrf sub_b+0
heinrichsweikamp
parents:
diff changeset
186 div32x16_2:
heinrichsweikamp
parents:
diff changeset
187 bcf STATUS,C
heinrichsweikamp
parents:
diff changeset
188 rlcf sub_a+0,F
heinrichsweikamp
parents:
diff changeset
189 rlcf sub_a+1,F
heinrichsweikamp
parents:
diff changeset
190 rlcf xA+0,F
heinrichsweikamp
parents:
diff changeset
191 rlcf xA+1,F
heinrichsweikamp
parents:
diff changeset
192 rlcf sub_b+0,F
heinrichsweikamp
parents:
diff changeset
193 rlcf sub_b+1,F
heinrichsweikamp
parents:
diff changeset
194 movf xB+1,W
heinrichsweikamp
parents:
diff changeset
195 subwf sub_b+1,W ; check if a>d
heinrichsweikamp
parents:
diff changeset
196 btfss STATUS,Z
heinrichsweikamp
parents:
diff changeset
197 bra div32x16_3
heinrichsweikamp
parents:
diff changeset
198 movf xB+0,W
heinrichsweikamp
parents:
diff changeset
199 subwf sub_b+0,W ; if msb equal then check lsb
heinrichsweikamp
parents:
diff changeset
200 div32x16_3:
heinrichsweikamp
parents:
diff changeset
201 btfss STATUS,C ; carry set if d>a
heinrichsweikamp
parents:
diff changeset
202 bra div32x16_4
heinrichsweikamp
parents:
diff changeset
203 movf xB+0,W ; d-a into d
heinrichsweikamp
parents:
diff changeset
204 subwf sub_b+0,F
heinrichsweikamp
parents:
diff changeset
205 btfss STATUS,C
heinrichsweikamp
parents:
diff changeset
206 decf sub_b+1,F
heinrichsweikamp
parents:
diff changeset
207 movf xB+1,W
heinrichsweikamp
parents:
diff changeset
208 subwf sub_b+1,F
heinrichsweikamp
parents:
diff changeset
209 bsf STATUS,C ; shift a 1 into b (result)
heinrichsweikamp
parents:
diff changeset
210 div32x16_4:
heinrichsweikamp
parents:
diff changeset
211 rlcf xC+0,F
heinrichsweikamp
parents:
diff changeset
212 rlcf xC+1,F
heinrichsweikamp
parents:
diff changeset
213 rlcf xC+2,F
heinrichsweikamp
parents:
diff changeset
214 rlcf xC+3,F
heinrichsweikamp
parents:
diff changeset
215 decfsz divB,F ; loop until all bits checked
heinrichsweikamp
parents:
diff changeset
216 bra div32x16_2
heinrichsweikamp
parents:
diff changeset
217 return
heinrichsweikamp
parents:
diff changeset
218
heinrichsweikamp
parents:
diff changeset
219 ;;=============================================================================
heinrichsweikamp
parents:
diff changeset
220 ;; u16 * u16 --> 32bit multiply (xA * xB --> xC)
heinrichsweikamp
parents:
diff changeset
221 ;; Used in interupt service routines, to compute temperature and pressure.
heinrichsweikamp
parents:
diff changeset
222 ;;
heinrichsweikamp
parents:
diff changeset
223 ; global isr_mult16x16
heinrichsweikamp
parents:
diff changeset
224 ;isr_mult16x16:
heinrichsweikamp
parents:
diff changeset
225 ; clrf isr_xC+2 ; Clear the High-Order Bits
heinrichsweikamp
parents:
diff changeset
226 ; clrf isr_xC+3
heinrichsweikamp
parents:
diff changeset
227 ; movf isr_xA, w ; Do the "L" Multiplication first
heinrichsweikamp
parents:
diff changeset
228 ; mulwf isr_xB
heinrichsweikamp
parents:
diff changeset
229 ; movf PRODL, w ; Save result
heinrichsweikamp
parents:
diff changeset
230 ; movwf isr_xC+0
heinrichsweikamp
parents:
diff changeset
231 ; movf PRODH, w
heinrichsweikamp
parents:
diff changeset
232 ; movwf isr_xC+1
heinrichsweikamp
parents:
diff changeset
233 ; movf isr_xA+0, w ; Do the "I" Multiplication
heinrichsweikamp
parents:
diff changeset
234 ; mulwf isr_xB+1
heinrichsweikamp
parents:
diff changeset
235 ; movf PRODL, w ; Save the Most Significant Byte First
heinrichsweikamp
parents:
diff changeset
236 ; addwf isr_xC+1, f
heinrichsweikamp
parents:
diff changeset
237 ; movf PRODH, w
heinrichsweikamp
parents:
diff changeset
238 ; addwfc isr_xC+2, f ; Add to the Last Result
heinrichsweikamp
parents:
diff changeset
239 ; movf isr_xA+1, w ; Do the "O" Multiplication
heinrichsweikamp
parents:
diff changeset
240 ; mulwf isr_xB
heinrichsweikamp
parents:
diff changeset
241 ; movf PRODL, w ; Add the Lower Byte Next
heinrichsweikamp
parents:
diff changeset
242 ; addwf isr_xC+1, f
heinrichsweikamp
parents:
diff changeset
243 ; movf PRODH, w ; Add the High Byte First
heinrichsweikamp
parents:
diff changeset
244 ; addwfc isr_xC+2, f
heinrichsweikamp
parents:
diff changeset
245 ; btfsc STATUS, C ; Add the Carry
heinrichsweikamp
parents:
diff changeset
246 ; incf isr_xC+3, f
heinrichsweikamp
parents:
diff changeset
247 ; movf isr_xA+1, w ; Do the "F" Multiplication
heinrichsweikamp
parents:
diff changeset
248 ; mulwf isr_xB+1
heinrichsweikamp
parents:
diff changeset
249 ; movf PRODL, w
heinrichsweikamp
parents:
diff changeset
250 ; addwf isr_xC+2, f
heinrichsweikamp
parents:
diff changeset
251 ; movf PRODH, w
heinrichsweikamp
parents:
diff changeset
252 ; addwfc isr_xC+3, f
heinrichsweikamp
parents:
diff changeset
253 ; return
heinrichsweikamp
parents:
diff changeset
254
heinrichsweikamp
parents:
diff changeset
255 ;=============================================================================
heinrichsweikamp
parents:
diff changeset
256 ; 24bit shift, repeted WREG times.
heinrichsweikamp
parents:
diff changeset
257 ; Because we shift less than 8bits, and keep only C[2:1], we don't care what
heinrichsweikamp
parents:
diff changeset
258 ; bit is inserted...
heinrichsweikamp
parents:
diff changeset
259 ;
heinrichsweikamp
parents:
diff changeset
260 global isr_shift_C31
heinrichsweikamp
parents:
diff changeset
261 isr_shift_C31:
heinrichsweikamp
parents:
diff changeset
262 rrcf isr_xC+3,F ; Shift the three bytes...
heinrichsweikamp
parents:
diff changeset
263 rrcf isr_xC+2,F
heinrichsweikamp
parents:
diff changeset
264 rrcf isr_xC+1,F
heinrichsweikamp
parents:
diff changeset
265 decfsz WREG
heinrichsweikamp
parents:
diff changeset
266 bra isr_shift_C31
heinrichsweikamp
parents:
diff changeset
267 return
heinrichsweikamp
parents:
diff changeset
268
heinrichsweikamp
parents:
diff changeset
269 ;=============================================================================
heinrichsweikamp
parents:
diff changeset
270 ; s16 * s16 --> 32bit multiply (xA * xB --> xC)
heinrichsweikamp
parents:
diff changeset
271 ; Signed multiplication.
heinrichsweikamp
parents:
diff changeset
272 ; Code from... the Pic18F documentation ;-)
heinrichsweikamp
parents:
diff changeset
273 global isr_unsigned_mult16x16
heinrichsweikamp
parents:
diff changeset
274 isr_unsigned_mult16x16:
heinrichsweikamp
parents:
diff changeset
275 MOVF isr_xA+0, W ; Lowest is simply a[0] * b[0]
heinrichsweikamp
parents:
diff changeset
276 MULWF isr_xB+0
heinrichsweikamp
parents:
diff changeset
277 MOVFF PRODL, isr_xC+0
heinrichsweikamp
parents:
diff changeset
278 MOVFF PRODH, isr_xC+1
heinrichsweikamp
parents:
diff changeset
279 ;
heinrichsweikamp
parents:
diff changeset
280 MOVF isr_xA+1, W ; And highest a[1] * b[1]
heinrichsweikamp
parents:
diff changeset
281 MULWF isr_xB+1
heinrichsweikamp
parents:
diff changeset
282 MOVFF PRODL, isr_xC+2
heinrichsweikamp
parents:
diff changeset
283 MOVFF PRODH, isr_xC+3
heinrichsweikamp
parents:
diff changeset
284 ;
heinrichsweikamp
parents:
diff changeset
285 MOVF isr_xA+0, W ; Intermediates do propagate:
heinrichsweikamp
parents:
diff changeset
286 MULWF isr_xB+1
heinrichsweikamp
parents:
diff changeset
287 MOVF PRODL, W
heinrichsweikamp
parents:
diff changeset
288 ADDWF isr_xC+1, F ; Add cross products
heinrichsweikamp
parents:
diff changeset
289 MOVF PRODH, W
heinrichsweikamp
parents:
diff changeset
290 ADDWFC isr_xC+2, F ; with propagated carry
heinrichsweikamp
parents:
diff changeset
291 CLRF WREG
heinrichsweikamp
parents:
diff changeset
292 ADDWFC isr_xC+3, F ; on the three bytes.
heinrichsweikamp
parents:
diff changeset
293 ;
heinrichsweikamp
parents:
diff changeset
294 MOVF isr_xA+1, W ; And the second one, similarly.
heinrichsweikamp
parents:
diff changeset
295 MULWF isr_xB+0
heinrichsweikamp
parents:
diff changeset
296 MOVF PRODL, W
heinrichsweikamp
parents:
diff changeset
297 ADDWF isr_xC+1, F ; Add cross products
heinrichsweikamp
parents:
diff changeset
298 MOVF PRODH, W
heinrichsweikamp
parents:
diff changeset
299 ADDWFC isr_xC+2, F
heinrichsweikamp
parents:
diff changeset
300 CLRF WREG
heinrichsweikamp
parents:
diff changeset
301 ADDWFC isr_xC+3, F
heinrichsweikamp
parents:
diff changeset
302 return
heinrichsweikamp
parents:
diff changeset
303
heinrichsweikamp
parents:
diff changeset
304 global isr_signed_mult16x16
heinrichsweikamp
parents:
diff changeset
305 isr_signed_mult16x16:
heinrichsweikamp
parents:
diff changeset
306 rcall isr_unsigned_mult16x16
heinrichsweikamp
parents:
diff changeset
307
heinrichsweikamp
parents:
diff changeset
308 ; Manage sign extension of operand B
heinrichsweikamp
parents:
diff changeset
309 BTFSS isr_xB+1,7 ; Is B negatif ?
heinrichsweikamp
parents:
diff changeset
310 BRA isr_signed_mult_checkA ; No: check ARG1
heinrichsweikamp
parents:
diff changeset
311 MOVF isr_xA+0, W ; Yes: add -65536 * A
heinrichsweikamp
parents:
diff changeset
312 SUBWF isr_xC+2, F
heinrichsweikamp
parents:
diff changeset
313 MOVF isr_xA+1, W
heinrichsweikamp
parents:
diff changeset
314 SUBWFB isr_xC+3, F
heinrichsweikamp
parents:
diff changeset
315 ; And of operand A
heinrichsweikamp
parents:
diff changeset
316 isr_signed_mult_checkA
heinrichsweikamp
parents:
diff changeset
317 BTFSS isr_xA+1, 7 ; Is A negatif ?
heinrichsweikamp
parents:
diff changeset
318 RETURN ; No: done
heinrichsweikamp
parents:
diff changeset
319 MOVF isr_xB+0, W
heinrichsweikamp
parents:
diff changeset
320 SUBWF isr_xC+2, F
heinrichsweikamp
parents:
diff changeset
321 MOVF isr_xB+1, W
heinrichsweikamp
parents:
diff changeset
322 SUBWFB isr_xC+3, F
heinrichsweikamp
parents:
diff changeset
323 RETURN
heinrichsweikamp
parents:
diff changeset
324
heinrichsweikamp
parents:
diff changeset
325 END