Mercurial > public > mk2
diff 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 |
line wrap: on
line diff
--- a/code_part1/OSTC_code_asm_part1/math.asm Wed Jan 19 12:24:51 2011 +0100 +++ b/code_part1/OSTC_code_asm_part1/math.asm Tue Jan 18 23:57:33 2011 +0100 @@ -16,9 +16,10 @@ ; Math routines -; written by: Matthias Heinrichs, info@heinrichsweikamp.com -; written: 10/30/05 -; last updated: 06/21/07 +; history: +; 2005-10-30: Written by Matthias Heinrichs, info@heinrichsweikamp.com +; 2007-06-21: MH last updated +; 2011-01-19: Clean up of isr variante. ; known bugs: ; ToDo: clean up! @@ -43,28 +44,6 @@ bra div16 return -div32: -; xC=xC(32Bit)/2^divB (divB: 8Bit only!) - bcf STATUS,C - rrcf xC+3 - rrcf xC+2 - rrcf xC+1 - rrcf xC+0 - decfsz divB - bra div32 - return - -invert_xC: - movf xC+1, w ; inverses xC+0:xC+1 - sublw 0xFF - movwf xC+1 - movf xC+0, w - bcf STATUS,C - sublw 0xFF - movwf xC+0 - return - - sub16: ; sub_c = sub_a - sub_b bcf neg_flag @@ -231,75 +210,20 @@ goto div32x16_2 return - -isr_div16: -; divA=divA/2^divB (divB: 8Bit only!) - bcf STATUS,C - rrcf isr_divA+1 - rrcf isr_divA - decfsz isr_divB - bra isr_div16 - return - -isr_div32: -; xC=xC(32Bit)/2^divB (divB: 8Bit only!) - bcf STATUS,C - rrcf isr_xC+3 - rrcf isr_xC+2 - rrcf isr_xC+1 - rrcf isr_xC+0 - decfsz isr_divB - bra isr_div32 - return - -isr_invert_xC: - movf isr_xC+1, w ; inverses xC+0:xC+1 - sublw 0xFF - movwf isr_xC+1 - movf isr_xC+0, w - bcf STATUS,C - sublw 0xFF - movwf isr_xC+0 - return - - -isr_sub16: -; sub_c = sub_a - sub_b - bcf neg_flag_isr - movf isr_sub_b+0, w ; Get Value to be subtracted - subwf isr_sub_a+0, w ; Do the High Byte - movwf isr_sub_c+0 - movf isr_sub_b+1, w ; Get the Value to be Subbed - subwfb isr_sub_a+1, w - movwf isr_sub_c+1 - btfsc STATUS,C - return ; result positve -; sub_c = sub_a - sub_b - bsf neg_flag_isr ; result negative - movff isr_sub_c+0,isr_sub_b+0 - movff isr_sub_c+1,isr_sub_b+1 - setf isr_sub_a - setf isr_sub_a+1 - movf isr_sub_b+0, w ; Get Value to be subtracted - subwf isr_sub_a+0, w ; Do the High Byte - movwf isr_sub_c+0 - movf isr_sub_b+1, w ; Get the Value to be Subbed - subwfb isr_sub_a+1, w - movwf isr_sub_c+1 - return - - +;============================================================================= +; u16 * u16 --> 32bit multiply (xA * xB --> xC) +; Used in interupt service routines, to compute temperature and pressure. +; isr_mult16x16: -;xA*xB=xC clrf isr_xC+2 ; Clear the High-Order Bits clrf isr_xC+3 movf isr_xA, w ; Do the "L" Multiplication first mulwf isr_xB movf PRODL, w ; Save result - movwf isr_xC + movwf isr_xC+0 movf PRODH, w movwf isr_xC+1 - movf isr_xA, w ; Do the "I" Multiplication + movf isr_xA+0, w ; Do the "I" Multiplication mulwf isr_xB+1 movf PRODL, w ; Save the Most Significant Byte First addwf isr_xC+1, f @@ -320,4 +244,70 @@ movf PRODH, w addwfc isr_xC+3, f return - \ No newline at end of file + +;============================================================================= +; 24bit shift, repeted WREG times. +; Because we shift less than 8bits, and keep only C[2:1], we don't care what +; bit is inserted... +; +isr_shift_C31: + rrcf isr_xC+3,F ; Shift the three bytes... + rrcf isr_xC+2,F + rrcf isr_xC+1,F + decfsz WREG + bra isr_shift_C31 + return + +;============================================================================= +; s16 * s16 --> 32bit multiply (xA * xB --> xC) +; Signed multiplication. +; Code from... the Pic18F documentation ;-) +isr_unsigned_mult16x16: + MOVF isr_xA+0, W ; Lowest is simply a[0] * b[0] + MULWF isr_xB+0 + MOVFF PRODL, isr_xC+0 + MOVFF PRODH, isr_xC+1 + ; + MOVF isr_xA+1, W ; And highest a[1] * b[1] + MULWF isr_xB+1 + MOVFF PRODL, isr_xC+2 + MOVFF PRODH, isr_xC+3 + ; + MOVF isr_xA+0, W ; Intermediates do propagate: + MULWF isr_xB+1 + MOVF PRODL, W + ADDWF isr_xC+1, F ; Add cross products + MOVF PRODH, W + ADDWFC isr_xC+2, F ; with propagated carry + CLRF WREG + ADDWFC isr_xC+3, F ; on the three bytes. + ; + MOVF isr_xA+1, W ; And the second one, similarly. + MULWF isr_xB+0 + MOVF PRODL, W + ADDWF isr_xC+1, F ; Add cross products + MOVF PRODH, W + ADDWFC isr_xC+2, F + CLRF WREG + ADDWFC isr_xC+3, F + return + +isr_signed_mult16x16: + rcall isr_unsigned_mult16x16 + + ; Manage sign extension of operand B + BTFSS isr_xB+1,7 ; Is B negatif ? + BRA isr_signed_mult_checkA ; No: check ARG1 + MOVF isr_xA+0, W ; Yes: add -65536 * A + SUBWF isr_xC+2, F + MOVF isr_xA+1, W + SUBWFB isr_xC+3, F + ; And of operand A +isr_signed_mult_checkA + BTFSS isr_xA+1, 7 ; Is A negatif ? + RETURN ; No: done + MOVF isr_xB+0, W + SUBWF isr_xC+2, F + MOVF isr_xB+1, W + SUBWFB isr_xC+3, F + RETURN