; CC8E Version 1.3, Copyright (c) B Knudsen Data ; C compiler for the PIC18 microcontrollers ; ************ 24. Jun 2009 9:08 ************* processor PIC18C252 radix DEC PRODH EQU 0xFF4 PRODL EQU 0xFF3 Carry EQU 0 arg1 EQU 0x00 arg2 EQU 0x03 rval EQU 0x06 sign EQU 0x09 arg1_3 EQU 0x00 arg2_3 EQU 0x03 rm EQU 0x06 counter EQU 0x09 c2 EQU 0x0A sign_2 EQU 0x0B ad_data EQU 0x0C tx EQU 0x0E av EQU 0x11 mg EQU 0x14 a EQU 0x17 vx EQU 0x1A prev EQU 0x1D kp EQU 0x20 GOTO main ; FILE 18\math24x.h ;#pragma library 1 ;/* ;fixed16_8 operator* _xmul16_8( fixed16_8 arg1, fixed16_8 arg2); ;fixedU16_8 operator* _xmulU16_8( fixedU16_8 arg1, fixedU16_8 arg2); ;fixed16_8 operator/ _xdiv16_8( fixed16_8 arg1, fixed16_8 arg2); ;fixedU16_8 operator/ _xdivU16_8( fixedU16_8 arg1, fixedU16_8 arg2); ;fixed8_16 operator* _xmul8_16( fixed8_16 arg1, fixed8_16 arg2); ;fixedU8_16 operator* _xmulU8_16( fixedU8_16 arg1, fixedU8_16 arg2); ;fixed8_16 operator/ _xdiv8_16( fixed8_16 arg1, fixed8_16 arg2); ;fixedU8_16 operator/ _xdivU8_16( fixedU8_16 arg1, fixedU8_16 arg2); ;*/ ; ;// DEFINABLE SYMBOLS (in the application code): ;//#define FX_OPTIM_SPEED // optimize for SPEED: default ;//#define FX_OPTIM_SIZE // optimize for SIZE ; ;#if __CoreSet__ < 1200 || __CoreSet__ >= 2100 ; #error math24x.h does not support the selected device ;#endif ; ;#if __CoreSet__ < 1600 ; #define genAdd(r,a) W=a; btsc(Carry); W=incsz(a); r+=W ; #define genSub(r,a) W=a; btss(Carry); W=incsz(a); r-=W ; #define genAddW(r,a) W=a; btsc(Carry); W=incsz(a); W=r+W ; #define genSubW(r,a) W=a; btss(Carry); W=incsz(a); W=r-W ;#else ; #define genAdd(r,a) W=a; r=addWFC(r) ; #define genSub(r,a) W=a; r=subWFB(r) ; #define genAddW(r,a) W=a; W=addWFC(r) ; #define genSubW(r,a) W=a; W=subWFB(r) ;#endif ; ;#if defined FX_OPTIM_SIZE ; // do not use 8*8 bit HW multiplier ;#elif __CoreSet__ == 1700 || __CoreSet__ == 1800 ; #define hw_mult8x8(a,b) W = a; multiply(b) ; #define loRES PRODL ; #define hiRES PRODH ;#elif __CoreSet__ == 2000 ; #define hw_mult8x8(a,b) W = a; multiply(b) ; #define loRES W ; #define hiRES MULH ;#endif ; ; ; ;fixed16_8 operator* _xmul16_8( fixed16_8 arg1, fixed16_8 arg2) ;{ _xmul16_8 ; fixed16_8 rval; ; char sign = arg1.high8 ^ arg2.high8; MOVF arg2+2,W,0 XORWF arg1+2,W,0 MOVWF sign,0 ; if (arg1 < 0) BTFSS arg1+2,7,0 BRA m001 ; arg1 = -arg1; BSF 0xFD8,Carry,0 MOVLW 0 SUBFWB arg1,1,0 SUBFWB arg1+1,1,0 SUBFWB arg1+2,1,0 ; if (arg2 < 0) m001 BTFSS arg2+2,7,0 BRA m002 ; arg2 = -arg2; BSF 0xFD8,Carry,0 MOVLW 0 SUBFWB arg2,1,0 SUBFWB arg2+1,1,0 SUBFWB arg2+2,1,0 ; ; #ifdef hw_mult8x8 ; ; hw_mult8x8( arg1.low8, arg2.low8); // p1 m002 MOVF arg1,W,0 MULWF arg2,0 ; rval.low8 = hiRES; MOVFF PRODH,rval ; rval.high16 = 0; CLRF rval+1,0 CLRF rval+2,0 ; ; hw_mult8x8( arg1.mid8, arg2.low8); // p2 MOVF arg1+1,W,0 MULWF arg2,0 ; rval.low8 += loRES; MOVF PRODL,W,0 ADDWF rval,1,0 ; genAdd( rval.mid8, hiRES); MOVF PRODH,W,0 ADDWFC rval+1,1,0 ; genAdd( rval.high8, 0); MOVLW 0 ADDWFC rval+2,1,0 ; ; hw_mult8x8( arg1.low8, arg2.mid8); // p2 MOVF arg1,W,0 MULWF arg2+1,0 ; rval.low8 += loRES; MOVF PRODL,W,0 ADDWF rval,1,0 ; genAdd( rval.mid8, hiRES); MOVF PRODH,W,0 ADDWFC rval+1,1,0 ; genAdd( rval.high8, 0); MOVLW 0 ADDWFC rval+2,1,0 ; ; hw_mult8x8( arg1.high8, arg2.low8); // p3 MOVF arg1+2,W,0 MULWF arg2,0 ; rval.mid8 += loRES; MOVF PRODL,W,0 ADDWF rval+1,1,0 ; genAdd( rval.high8, hiRES); MOVF PRODH,W,0 ADDWFC rval+2,1,0 ; ; hw_mult8x8( arg1.mid8, arg2.mid8); // p3 MOVF arg1+1,W,0 MULWF arg2+1,0 ; rval.mid8 += loRES; MOVF PRODL,W,0 ADDWF rval+1,1,0 ; genAdd( rval.high8, hiRES); MOVF PRODH,W,0 ADDWFC rval+2,1,0 ; ; hw_mult8x8( arg1.low8, arg2.high8); // p3 MOVF arg1,W,0 MULWF arg2+2,0 ; rval.mid8 += loRES; MOVF PRODL,W,0 ADDWF rval+1,1,0 ; genAdd( rval.high8, hiRES); MOVF PRODH,W,0 ADDWFC rval+2,1,0 ; ; hw_mult8x8( arg1.high8, arg2.mid8); // p4 MOVF arg1+2,W,0 MULWF arg2+1,0 ; rval.high8 += loRES; MOVF PRODL,W,0 ADDWF rval+2,1,0 ; ; hw_mult8x8( arg1.mid8, arg2.high8); // p4 MOVF arg1+1,W,0 MULWF arg2+2,0 ; rval.high8 += loRES; MOVF PRODL,W,0 ADDWF rval+2,1,0 ; ; #else ; ; char counter = sizeof(arg1)*8; ; char rvalL = 0; ; do { ; Carry = 0; ; rvalL = rl( rvalL); ; rval = rl( rval); ; arg1 = rl( arg1); ; if (Carry) { ; rvalL += arg2.low8; ; genAdd( rval.low8, arg2.mid8); ; genAdd( rval.mid8, arg2.high8); ; if (Carry) ; rval.high8++; ; } ; counter = decsz(counter); ; } while (1); ; ; #endif ; ; if (sign & 0x80) BTFSS sign,7,0 BRA m003 ; rval = -rval; BSF 0xFD8,Carry,0 MOVLW 0 SUBFWB rval,1,0 SUBFWB rval+1,1,0 SUBFWB rval+2,1,0 ; return rval; m003 MOVF rval,W,0 RETURN ;} ; ; ;fixedU16_8 operator* _xmulU16_8( fixedU16_8 arg1, fixedU16_8 arg2) ;{ _xmulU16_8 ; fixedU16_8 rval; ; ; #ifdef hw_mult8x8 ; ; hw_mult8x8( arg1.low8, arg2.low8); // p1 ; rval.low8 = hiRES; ; rval.high16 = 0; ; ; hw_mult8x8( arg1.mid8, arg2.low8); // p2 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.low8, arg2.mid8); // p2 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.high8, arg2.low8); // p3 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.mid8, arg2.mid8); // p3 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.low8, arg2.high8); // p3 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.high8, arg2.mid8); // p4 ; rval.high8 += loRES; ; ; hw_mult8x8( arg1.mid8, arg2.high8); // p4 ; rval.high8 += loRES; ; ; #else ; ; char counter = sizeof(arg1)*8; ; char rvalL = 0; ; do { ; Carry = 0; ; rvalL = rl( rvalL); ; rval = rl( rval); ; arg1 = rl( arg1); ; if (Carry) { ; rvalL += arg2.low8; ; genAdd( rval.low8, arg2.mid8); ; genAdd( rval.mid8, arg2.high8); ; if (Carry) ; rval.high8++; ; } ; counter = decsz(counter); ; } while (1); ; ; #endif ; ; return rval; ;} ; ; ;fixed16_8 operator/ _xdiv16_8( fixed16_8 arg1, fixed16_8 arg2) ;{ _xdiv16_8 ; fixedU16_8 rm = 0; CLRF rm,0 CLRF rm+1,0 CLRF rm+2,0 ; char counter = sizeof(arg1)*8+8+1; MOVLW 33 MOVWF counter,0 ; char c2 = sizeof(arg1)*8 + 1; MOVLW 25 MOVWF c2,0 ; char sign = arg1.high8 ^ arg2.high8; MOVF arg2_3+2,W,0 XORWF arg1_3+2,W,0 MOVWF sign_2,0 ; if (arg1 < 0) { BTFSS arg1_3+2,7,0 BRA m005 ; INVERT: ; arg1 = -arg1; m004 BSF 0xFD8,Carry,0 MOVLW 0 SUBFWB arg1_3,1,0 SUBFWB arg1_3+1,1,0 SUBFWB arg1_3+2,1,0 ; if (c2 & 0x80) BTFSC c2,7,0 ; goto EXIT; BRA m008 ; } ; if (arg2 < 0) m005 BTFSS arg2_3+2,7,0 BRA m007 ; arg2 = -arg2; BSF 0xFD8,Carry,0 MOVLW 0 SUBFWB arg2_3,1,0 SUBFWB arg2_3+1,1,0 SUBFWB arg2_3+2,1,0 ; goto ENTRY; BRA m007 ; do { ; c2 = decsz(c2); m006 DECFSZ c2,1,0 ; btsc(c2.7); BTFSC c2,7,0 ; Carry = 0; BCF 0xFD8,Carry,0 ; rm = rl( rm); RLCF rm,1,0 RLCF rm+1,1,0 RLCF rm+2,1,0 ; W = rm.low8 - arg2.low8; MOVF arg2_3,W,0 SUBWF rm,W,0 ; genSubW( rm.mid8, arg2.mid8); MOVF arg2_3+1,W,0 SUBWFB rm+1,W,0 ; genSubW( rm.high8, arg2.high8); MOVF arg2_3+2,W,0 SUBWFB rm+2,W,0 ; if (!Carry) ; goto ENTRY; BNC m007 ; rm.high8 = W; MOVWF rm+2,0 ; rm.low8 -= arg2.low8; MOVF arg2_3,W,0 SUBWF rm,1,0 ; genSub( rm.mid8, arg2.mid8); MOVF arg2_3+1,W,0 SUBWFB rm+1,1,0 ; Carry = 1; BSF 0xFD8,Carry,0 ; ENTRY: ; arg1 = rl( arg1); m007 RLCF arg1_3,1,0 RLCF arg1_3+1,1,0 RLCF arg1_3+2,1,0 ; counter = decsz(counter); DECFSZ counter,1,0 ; } while (1); BRA m006 ; if (sign & 0x80) BTFSC sign_2,7,0 ; goto INVERT; BRA m004 ; EXIT: ; return arg1; m008 MOVF arg1_3,W,0 RETURN ;} ; ; ; ;fixedU16_8 operator/ _xdivU16_8( fixedU16_8 arg1, fixedU16_8 arg2) ;{ _xdivU16_8 ; fixedU16_8 rm = 0; ; char counter = sizeof(arg1)*8+8+1; ; char c2 = sizeof(arg1)*8 + 1; ; goto ENTRY; ; do { ; c2 = decsz(c2); ; btsc(c2.7); ; Carry = 0; ; rm = rl( rm); ; if (Carry) ; goto SUBTRACT; ; W = rm.low8 - arg2.low8; ; genSubW( rm.mid8, arg2.mid8); ; genSubW( rm.high8, arg2.high8); ; if (!Carry) ; goto ENTRY; ; SUBTRACT: ; rm.low8 -= arg2.low8; ; genSub( rm.mid8, arg2.mid8); ; genSub( rm.high8, arg2.high8); ; Carry = 1; ; ENTRY: ; arg1 = rl( arg1); ; counter = decsz(counter); ; } while (1); ; return arg1; ;} ; ; ; ; ;fixed8_16 operator* _xmul8_16( fixed8_16 arg1, fixed8_16 arg2) ;{ _xmul8_16 ; fixed8_16 rval; ; char sign = arg1.high8 ^ arg2.high8; ; if (arg1 < 0) ; arg1 = -arg1; ; if (arg2 < 0) ; arg2 = -arg2; ; ; #ifdef hw_mult8x8 ; ; uns8 tmpL; ; ; hw_mult8x8( arg1.low8, arg2.low8); // p1 ; tmpL = hiRES; ; rval = 0; ; ; hw_mult8x8( arg1.mid8, arg2.low8); // p2 ; tmpL += loRES; ; genAdd( rval.low8, hiRES); ; genAdd( rval.mid8, 0); ; ; hw_mult8x8( arg1.low8, arg2.mid8); // p2 ; tmpL += loRES; ; genAdd( rval.low8, hiRES); ; genAdd( rval.mid8, 0); ; ; hw_mult8x8( arg1.high8, arg2.low8); // p3 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.mid8, arg2.mid8); // p3 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.low8, arg2.high8); // p3 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.high8, arg2.mid8); // p4 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.mid8, arg2.high8); // p4 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.high8, arg2.high8); // p5 ; rval.high8 += loRES; ; ; #else ; ; char counter = sizeof(arg2)*8; ; uns8 rvalH = 0; ; rval.high16 = 0; ; ; do { ; arg2 = rr( arg2); ; if (Carry) { ; rval.mid8 += arg1.low8; ; genAdd( rval.high8, arg1.mid8); ; genAdd( rvalH, arg1.high8); ; } ; rvalH = rr( rvalH); ; rval = rr( rval); ; counter = decsz(counter); ; } while (1); ; ; #endif ; ; if (sign & 0x80) ; rval = -rval; ; return rval; ;} ; ; ;fixedU8_16 operator* _xmulU8_16( fixedU8_16 arg1, fixedU8_16 arg2) ;{ _xmulU8_16 ; fixedU8_16 rval; ; ; #ifdef hw_mult8x8 ; ; uns8 tmpL; ; ; hw_mult8x8( arg1.low8, arg2.low8); // p1 ; tmpL = hiRES; ; rval = 0; ; ; hw_mult8x8( arg1.mid8, arg2.low8); // p2 ; tmpL += loRES; ; genAdd( rval.low8, hiRES); ; genAdd( rval.mid8, 0); ; ; hw_mult8x8( arg1.low8, arg2.mid8); // p2 ; tmpL += loRES; ; genAdd( rval.low8, hiRES); ; genAdd( rval.mid8, 0); ; ; hw_mult8x8( arg1.high8, arg2.low8); // p3 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.mid8, arg2.mid8); // p3 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.low8, arg2.high8); // p3 ; rval.low8 += loRES; ; genAdd( rval.mid8, hiRES); ; genAdd( rval.high8, 0); ; ; hw_mult8x8( arg1.high8, arg2.mid8); // p4 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.mid8, arg2.high8); // p4 ; rval.mid8 += loRES; ; genAdd( rval.high8, hiRES); ; ; hw_mult8x8( arg1.high8, arg2.high8); // p5 ; rval.high8 += loRES; ; ; #else ; ; char counter = sizeof(arg2)*8; ; uns8 rvalH = 0; ; rval.high16 = 0; ; do { ; arg2 = rr( arg2); ; if (Carry) { ; rval.mid8 += arg1.low8; ; genAdd( rval.high8, arg1.mid8); ; genAdd( rvalH, arg1.high8); ; } ; rvalH = rr( rvalH); ; rval = rr( rval); ; counter = decsz(counter); ; } while (1); ; ; #endif ; ; return rval; ;} ; ; ;fixed8_16 operator/ _xdiv8_16( fixed8_16 arg1, fixed8_16 arg2) ;{ _xdiv8_16 ; fixedU8_16 rm = 0; ; char counter = sizeof(arg1)*8+16+1; ; char c2 = sizeof(arg1)*8 + 1; ; char sign = arg1.high8 ^ arg2.high8; ; if (arg1 < 0) { ; INVERT: ; arg1 = -arg1; ; if (c2 & 0x80) ; goto EXIT; ; } ; if (arg2 < 0) ; arg2 = -arg2; ; goto ENTRY; ; do { ; c2 = decsz(c2); ; btsc(c2.7); ; Carry = 0; ; rm = rl( rm); ; W = rm.low8 - arg2.low8; ; genSubW( rm.mid8, arg2.mid8); ; genSubW( rm.high8, arg2.high8); ; if (!Carry) ; goto ENTRY; ; rm.high8 = W; ; rm.low8 -= arg2.low8; ; genSub( rm.mid8, arg2.mid8); ; Carry = 1; ; ENTRY: ; arg1 = rl( arg1); ; counter = decsz(counter); ; } while (1); ; if (sign & 0x80) ; goto INVERT; ; EXIT: ; return arg1; ;} ; ; ; ;fixedU8_16 operator/ _xdivU8_16( fixedU8_16 arg1, fixedU8_16 arg2) ;{ _xdivU8_16 ; fixedU8_16 rm = 0; ; char counter = sizeof(arg1)*8+16+1; ; char c2 = sizeof(arg1)*8 + 1; ; goto ENTRY; ; do { ; c2 = decsz(c2); ; btsc(c2.7); ; Carry = 0; ; rm = rl( rm); ; if (Carry) ; goto SUBTRACT; ; W = rm.low8 - arg2.low8; ; genSubW( rm.mid8, arg2.mid8); ; genSubW( rm.high8, arg2.high8); ; if (!Carry) ; goto ENTRY; ; SUBTRACT: ; rm.low8 -= arg2.low8; ; genSub( rm.mid8, arg2.mid8); ; genSub( rm.high8, arg2.high8); ; Carry = 1; ; ENTRY: ; arg1 = rl( arg1); ; counter = decsz(counter); ; } while (1); ; return arg1; ; FILE 18\demo-fxm.c ; ;#pragma chip PIC18C252 ;#include "math24x.h" ;uns16 ad_data; ;fixed16_8 tx, av, mg, a, vx, prev, kp; ; ;void main(void) ;{ main ; vx = 3.127; MOVLW 33 MOVWF vx,0 MOVLW 3 MOVWF vx+1,0 CLRF vx+2,0 ; tx += ad_data; // automatic type cast MOVF ad_data,W,0 ADDWF tx+1,1,0 MOVF ad_data+1,W,0 ADDWFC tx+2,1,0 ; ad_data = kp; // assign integer part MOVFF kp+1,ad_data MOVFF kp+2,ad_data+1 ; if ( tx < 0) BTFSS tx+2,7,0 BRA m009 ; tx = -tx; // make positive BSF 0xFD8,Carry,0 MOVLW 0 SUBFWB tx,1,0 SUBFWB tx+1,1,0 SUBFWB tx+2,1,0 ; av = tx/20.0; m009 MOVFF tx,arg1_3 MOVFF tx+1,arg1_3+1 MOVFF tx+2,arg1_3+2 CLRF arg2_3,0 MOVLW 20 MOVWF arg2_3+1,0 CLRF arg2_3+2,0 RCALL _xdiv16_8 MOVFF arg1_3,av MOVFF arg1_3+1,av+1 MOVFF arg1_3+2,av+2 ; mg = av * 1.25; MOVFF av,arg1 MOVFF av+1,arg1+1 MOVFF av+2,arg1+2 MOVLW 64 MOVWF arg2,0 MOVLW 1 MOVWF arg2+1,0 CLRF arg2+2,0 RCALL _xmul16_8 MOVFF rval,mg MOVFF rval+1,mg+1 MOVFF rval+2,mg+2 ; a = mg * 0.98; // 0.980469: error on constant: 0.000478 MOVFF mg,arg1 MOVFF mg+1,arg1+1 MOVFF mg+2,arg1+2 MOVLW 251 MOVWF arg2,0 CLRF arg2+1,0 CLRF arg2+2,0 RCALL _xmul16_8 MOVFF rval,a MOVFF rval+1,a+1 MOVFF rval+2,a+2 ; prev = vx; MOVFF vx,prev MOVFF vx+1,prev+1 MOVFF vx+2,prev+2 ; vx = a/5.0 + prev; MOVFF a,arg1_3 MOVFF a+1,arg1_3+1 MOVFF a+2,arg1_3+2 CLRF arg2_3,0 MOVLW 5 MOVWF arg2_3+1,0 CLRF arg2_3+2,0 RCALL _xdiv16_8 MOVF prev,W,0 ADDWF arg1_3,W,0 MOVWF vx,0 MOVF prev+1,W,0 ADDWFC arg1_3+1,W,0 MOVWF vx+1,0 MOVF prev+2,W,0 ADDWFC arg1_3+2,W,0 MOVWF vx+2,0 ; ; kp = vx * 0.036; // 0.03515626: error on constant: 0.024 MOVFF vx,arg1 MOVFF vx+1,arg1+1 MOVFF vx+2,arg1+2 MOVLW 9 MOVWF arg2,0 CLRF arg2+1,0 CLRF arg2+2,0 RCALL _xmul16_8 MOVFF rval,kp MOVFF rval+1,kp+1 MOVFF rval+2,kp+2 ; kp = vx / (1.0/0.036); // 27.7773437 error on constant: 0.0000156 MOVFF vx,arg1_3 MOVFF vx+1,arg1_3+1 MOVFF vx+2,arg1_3+2 MOVLW 199 MOVWF arg2_3,0 MOVLW 27 MOVWF arg2_3+1,0 CLRF arg2_3+2,0 RCALL _xdiv16_8 MOVFF arg1_3,kp MOVFF arg1_3+1,kp+1 MOVFF arg1_3+2,kp+2 ;} SLEEP RESET END ; *** KEY INFO *** ; 0x000004 74 word(s) 0 % : _xmul16_8 ; 0x000098 55 word(s) 0 % : _xdiv16_8 ; 0x000106 135 word(s) 0 % : main ; RAM usage: 35 bytes (12 local), 1501 bytes free ; Maximum call level: 1 ; Total of 266 code words (1 %)