Mercurial > public > mk2
comparison code_part1/OSTC_code_asm_part1/math.asm @ 161:8d6aca08f66b
Use signed arithmetic for pressure/temperature compensation.
author | JeanDo |
---|---|
date | Tue, 18 Jan 2011 23:57:33 +0100 |
parents | 64109f6fb3d1 |
children | 06299199dfb9 |
comparison
equal
deleted
inserted
replaced
160:0ee809806454 | 161:8d6aca08f66b |
---|---|
14 ; You should have received a copy of the GNU General Public License | 14 ; You should have received a copy of the GNU General Public License |
15 ; along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 ; along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 |
17 | 17 |
18 ; Math routines | 18 ; Math routines |
19 ; written by: Matthias Heinrichs, info@heinrichsweikamp.com | 19 ; history: |
20 ; written: 10/30/05 | 20 ; 2005-10-30: Written by Matthias Heinrichs, info@heinrichsweikamp.com |
21 ; last updated: 06/21/07 | 21 ; 2007-06-21: MH last updated |
22 ; 2011-01-19: Clean up of isr variante. | |
22 ; known bugs: | 23 ; known bugs: |
23 ; ToDo: clean up! | 24 ; ToDo: clean up! |
24 | 25 |
25 | 26 |
26 convert_time: ; converts hi:lo in minutes to hours (hi) and minutes (lo) | 27 convert_time: ; converts hi:lo in minutes to hours (hi) and minutes (lo) |
40 rrcf divA+1 | 41 rrcf divA+1 |
41 rrcf divA | 42 rrcf divA |
42 decfsz divB | 43 decfsz divB |
43 bra div16 | 44 bra div16 |
44 return | 45 return |
45 | |
46 div32: | |
47 ; xC=xC(32Bit)/2^divB (divB: 8Bit only!) | |
48 bcf STATUS,C | |
49 rrcf xC+3 | |
50 rrcf xC+2 | |
51 rrcf xC+1 | |
52 rrcf xC+0 | |
53 decfsz divB | |
54 bra div32 | |
55 return | |
56 | |
57 invert_xC: | |
58 movf xC+1, w ; inverses xC+0:xC+1 | |
59 sublw 0xFF | |
60 movwf xC+1 | |
61 movf xC+0, w | |
62 bcf STATUS,C | |
63 sublw 0xFF | |
64 movwf xC+0 | |
65 return | |
66 | |
67 | 46 |
68 sub16: | 47 sub16: |
69 ; sub_c = sub_a - sub_b | 48 ; sub_c = sub_a - sub_b |
70 bcf neg_flag | 49 bcf neg_flag |
71 movf sub_b+0, W ; Get Value to be subtracted | 50 movf sub_b+0, W ; Get Value to be subtracted |
229 rlcf xC+3,F | 208 rlcf xC+3,F |
230 decfsz divB,F ; loop until all bits checked | 209 decfsz divB,F ; loop until all bits checked |
231 goto div32x16_2 | 210 goto div32x16_2 |
232 return | 211 return |
233 | 212 |
234 | 213 ;============================================================================= |
235 isr_div16: | 214 ; u16 * u16 --> 32bit multiply (xA * xB --> xC) |
236 ; divA=divA/2^divB (divB: 8Bit only!) | 215 ; Used in interupt service routines, to compute temperature and pressure. |
237 bcf STATUS,C | 216 ; |
238 rrcf isr_divA+1 | |
239 rrcf isr_divA | |
240 decfsz isr_divB | |
241 bra isr_div16 | |
242 return | |
243 | |
244 isr_div32: | |
245 ; xC=xC(32Bit)/2^divB (divB: 8Bit only!) | |
246 bcf STATUS,C | |
247 rrcf isr_xC+3 | |
248 rrcf isr_xC+2 | |
249 rrcf isr_xC+1 | |
250 rrcf isr_xC+0 | |
251 decfsz isr_divB | |
252 bra isr_div32 | |
253 return | |
254 | |
255 isr_invert_xC: | |
256 movf isr_xC+1, w ; inverses xC+0:xC+1 | |
257 sublw 0xFF | |
258 movwf isr_xC+1 | |
259 movf isr_xC+0, w | |
260 bcf STATUS,C | |
261 sublw 0xFF | |
262 movwf isr_xC+0 | |
263 return | |
264 | |
265 | |
266 isr_sub16: | |
267 ; sub_c = sub_a - sub_b | |
268 bcf neg_flag_isr | |
269 movf isr_sub_b+0, w ; Get Value to be subtracted | |
270 subwf isr_sub_a+0, w ; Do the High Byte | |
271 movwf isr_sub_c+0 | |
272 movf isr_sub_b+1, w ; Get the Value to be Subbed | |
273 subwfb isr_sub_a+1, w | |
274 movwf isr_sub_c+1 | |
275 btfsc STATUS,C | |
276 return ; result positve | |
277 ; sub_c = sub_a - sub_b | |
278 bsf neg_flag_isr ; result negative | |
279 movff isr_sub_c+0,isr_sub_b+0 | |
280 movff isr_sub_c+1,isr_sub_b+1 | |
281 setf isr_sub_a | |
282 setf isr_sub_a+1 | |
283 movf isr_sub_b+0, w ; Get Value to be subtracted | |
284 subwf isr_sub_a+0, w ; Do the High Byte | |
285 movwf isr_sub_c+0 | |
286 movf isr_sub_b+1, w ; Get the Value to be Subbed | |
287 subwfb isr_sub_a+1, w | |
288 movwf isr_sub_c+1 | |
289 return | |
290 | |
291 | |
292 isr_mult16x16: | 217 isr_mult16x16: |
293 ;xA*xB=xC | |
294 clrf isr_xC+2 ; Clear the High-Order Bits | 218 clrf isr_xC+2 ; Clear the High-Order Bits |
295 clrf isr_xC+3 | 219 clrf isr_xC+3 |
296 movf isr_xA, w ; Do the "L" Multiplication first | 220 movf isr_xA, w ; Do the "L" Multiplication first |
297 mulwf isr_xB | 221 mulwf isr_xB |
298 movf PRODL, w ; Save result | 222 movf PRODL, w ; Save result |
299 movwf isr_xC | 223 movwf isr_xC+0 |
300 movf PRODH, w | 224 movf PRODH, w |
301 movwf isr_xC+1 | 225 movwf isr_xC+1 |
302 movf isr_xA, w ; Do the "I" Multiplication | 226 movf isr_xA+0, w ; Do the "I" Multiplication |
303 mulwf isr_xB+1 | 227 mulwf isr_xB+1 |
304 movf PRODL, w ; Save the Most Significant Byte First | 228 movf PRODL, w ; Save the Most Significant Byte First |
305 addwf isr_xC+1, f | 229 addwf isr_xC+1, f |
306 movf PRODH, w | 230 movf PRODH, w |
307 addwfc isr_xC+2, f ; Add to the Last Result | 231 addwfc isr_xC+2, f ; Add to the Last Result |
318 movf PRODL, w | 242 movf PRODL, w |
319 addwf isr_xC+2, f | 243 addwf isr_xC+2, f |
320 movf PRODH, w | 244 movf PRODH, w |
321 addwfc isr_xC+3, f | 245 addwfc isr_xC+3, f |
322 return | 246 return |
323 | 247 |
248 ;============================================================================= | |
249 ; 24bit shift, repeted WREG times. | |
250 ; Because we shift less than 8bits, and keep only C[2:1], we don't care what | |
251 ; bit is inserted... | |
252 ; | |
253 isr_shift_C31: | |
254 rrcf isr_xC+3,F ; Shift the three bytes... | |
255 rrcf isr_xC+2,F | |
256 rrcf isr_xC+1,F | |
257 decfsz WREG | |
258 bra isr_shift_C31 | |
259 return | |
260 | |
261 ;============================================================================= | |
262 ; s16 * s16 --> 32bit multiply (xA * xB --> xC) | |
263 ; Signed multiplication. | |
264 ; Code from... the Pic18F documentation ;-) | |
265 isr_unsigned_mult16x16: | |
266 MOVF isr_xA+0, W ; Lowest is simply a[0] * b[0] | |
267 MULWF isr_xB+0 | |
268 MOVFF PRODL, isr_xC+0 | |
269 MOVFF PRODH, isr_xC+1 | |
270 ; | |
271 MOVF isr_xA+1, W ; And highest a[1] * b[1] | |
272 MULWF isr_xB+1 | |
273 MOVFF PRODL, isr_xC+2 | |
274 MOVFF PRODH, isr_xC+3 | |
275 ; | |
276 MOVF isr_xA+0, W ; Intermediates do propagate: | |
277 MULWF isr_xB+1 | |
278 MOVF PRODL, W | |
279 ADDWF isr_xC+1, F ; Add cross products | |
280 MOVF PRODH, W | |
281 ADDWFC isr_xC+2, F ; with propagated carry | |
282 CLRF WREG | |
283 ADDWFC isr_xC+3, F ; on the three bytes. | |
284 ; | |
285 MOVF isr_xA+1, W ; And the second one, similarly. | |
286 MULWF isr_xB+0 | |
287 MOVF PRODL, W | |
288 ADDWF isr_xC+1, F ; Add cross products | |
289 MOVF PRODH, W | |
290 ADDWFC isr_xC+2, F | |
291 CLRF WREG | |
292 ADDWFC isr_xC+3, F | |
293 return | |
294 | |
295 isr_signed_mult16x16: | |
296 rcall isr_unsigned_mult16x16 | |
297 | |
298 ; Manage sign extension of operand B | |
299 BTFSS isr_xB+1,7 ; Is B negatif ? | |
300 BRA isr_signed_mult_checkA ; No: check ARG1 | |
301 MOVF isr_xA+0, W ; Yes: add -65536 * A | |
302 SUBWF isr_xC+2, F | |
303 MOVF isr_xA+1, W | |
304 SUBWFB isr_xC+3, F | |
305 ; And of operand A | |
306 isr_signed_mult_checkA | |
307 BTFSS isr_xA+1, 7 ; Is A negatif ? | |
308 RETURN ; No: done | |
309 MOVF isr_xB+0, W | |
310 SUBWF isr_xC+2, F | |
311 MOVF isr_xB+1, W | |
312 SUBWFB isr_xC+3, F | |
313 RETURN |