; (See http://techref.massmind.org/techref/microchip/pfu/pfu.c ; for the original C source code) ; CC5X Version 3.0E, Copyright (c) B. Knudsen Data ; C compiler for the PICmicro family ; ************ 16. Dec 1999 17:42 ************* processor 16C62A radix DEC INDF EQU 0x00 FSR EQU 0x04 Carry EQU 0 Zero_ EQU 2 a8 EQU 0x22 a16 EQU 0x23 a24 EQU 0x25 a32 EQU 0x28 b8 EQU 0x2C b16 EQU 0x2D b24 EQU 0x2F b32 EQU 0x32 r8 EQU 0x36 r16 EQU 0x37 r24 EQU 0x39 r32 EQU 0x3C r40 EQU 0x40 r48 EQU 0x45 r64 EQU 0x4B Overflow EQU 0 ZeroDiv EQU 1 q8 EQU 0x54 ww EQU 0x7F ix EQU 0x7F ix_2 EQU 0x7F m EQU 0x7F ix_3 EQU 0x7F ix_4 EQU 0x7F m_2 EQU 0x7F ix_5 EQU 0x7F ix_6 EQU 0x7F m_3 EQU 0x7F p EQU 0x7F ix_7 EQU 0x7F ix_8 EQU 0x7F m_4 EQU 0x7F p_2 EQU 0x7F ix_9 EQU 0x7F ix_10 EQU 0x7F ix_11 EQU 0x7F ix_12 EQU 0x7F ix_13 EQU 0x7F ix_14 EQU 0x7F ix_15 EQU 0x7F ix_16 EQU 0x7F ix_17 EQU 0x20 oldCy EQU 0x21 GOTO main ; FILE D:\PFU\PFU.C ; ;/*======================================================================* ; | Planet Fastest Unsigned PICmicro Math | ; | (c) 1999 Jose Luiz Pinto Souto | ; | souto@cryogen.com | ; | | ; | Loop version, smallest code. All timming includes CALL and | ; | RETURN instructions. | ; | | ; | Compiled with CC5X, see also CC5xfree, a free 1K limited | ; | C compiler from B. Knudsen Data - www.bknd.com. | ; | | ; | For algorithm details see Microchip's application note AN617. | ; | PICmicro is registered Trademark of Microchip Technology Inc. | ; | Alpha version - please report any bug to e-mail above. | ; | If any faster algorithm is found, please report. | ; *======================================================================*/ ; ;/* this software has been released to increase critical-mass PIC usage */ ; ;/* ; YOU MAY USE THIS SOFTWARE OR PART OF IT AS LONG AS YOU KEEP THE ; COPYRIGHT NOTICE. COMERCIAL PRODUCTS SHOULD HAVE A PUBLIC REFERENCE ; TO AUTHOR. ; ; THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, ; EXPRESSED, IMPLIED OR OTHERWISE, INCLUDING AND WITHOUT LIMITATION, ; ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INCIDENTAL, ; INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT ; LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, LOSS ; OF INFORMATION, OR ANY OTHER LOSS) , WHETHER OR NOT ADVISED OF THE ; POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF ; OR IN CONNECTION WITH THE USE OR INABILITY TO USE THIS SOFTWARE. ;*/ ; ; ;#include <16c62a.h> ;#pragma update_RP 0 // OFF ; ;#define uns40 unsigned int ;#define uns48 unsigned int ;#define uns56 unsigned int ;#define uns64 unsigned int ; ;uns8 a8; // Load the 1st operand ( 8 bits ) ;uns16 a16; // Load the 1st operand ( 16 bits ) ;uns24 a24; // Load the 1st operand ( 24 bits ) ;uns32 a32; // Load the 1st operand ( 32 bits ) ; ;uns8 b8; // Load the 2nd operand ( 8 bits ) ;uns16 b16; // Load the 2nd operand ( 16 bits ) ;uns24 b24; // Load the 2nd operand ( 24 bits ) ;uns32 b32; // Load the 2nd operand ( 32 bits ) ; ;uns8 r8; // The 8 bits result ;uns16 r16; // The 16 bits result ;uns24 r24; // The 24 bits result ;uns32 r32; // The 32 bits result ;uns40 r40[5]; // The 40 bits result ;uns48 r48[6]; // The 48 bits result ;uns64 r64[8]; // The 64 bits result ; ;bit Overflow; // Division Overflow flag ;bit ZeroDiv; // Division Divisin by Zero flag ; ;uns8 q8; // The 8 bits quotient ;uns16 q16; // The 16 bits quotient ;uns24 q24; // The 24 bits quotient ; ;/*======================================================================*/ ;/* Prototypes */ ;/*======================================================================*/ ; ;void negate8 (void); ;void negate16 (void); ;void negate24 (void); ;void negate32 (void); ; ;void negate8a (void); ;void negate16a (void); ;void negate24a (void); ;void negate32a (void); ; ;void negate8b (void); ;void negate16b (void); ;void negate24b (void); ;void negate32b (void); ; ;/*----------------*/ ; ;void add8 (void); ;void add16 (void); ;void add24 (void); ;void add32 (void); ; ;void add8a (void); ;void add16a (void); ;void add24a (void); ;void add32a (void); ; ;void add8b (void); ;void add16b (void); ;void add24b (void); ;void add32b (void); ; ;/*----------------*/ ; ;void sub8 (void); ;void sub16 (void); ;void sub24 (void); ;void sub32 (void); ; ;void sub8a (void); ;void sub16a (void); ;void sub24a (void); ;void sub32a (void); ; ;/*-------------------*/ ; ;void mpy8x8 (void); ; ;void mpy16x8 (void); ;void mpy24x8 (void); ;void mpy32x8 (void); ; ;void mpy16x8a (void); ;void mpy24x8a (void); ;void mpy32x8a (void); ; ;void mpy16x16 (void); ;void mpy24x16 (void); ;void mpy32x16 (void); ; ;void mpy16x16a (void); ;void mpy24x16a (void); ;void mpy32x16a (void); ; ;void mpy32x32 (void); ;void mpy32x32a (void); ; ; ;/*======================================================================*/ ;void negate8 (void) // r8 = -b8 ;/*======================================================================*/ ; ;{ negate8 COMF b8,W ; r8 = ~b8; MOVWF r8 INCF r8,1 ; r8++; ; RETURN ;} // 4 instructions, 5 cycles ; ;/*======================================================================*/ ;void negate8a (void) // b8 = -b8 ;/*======================================================================*/ ; ;{ negate8a COMF b8,1 ; b8 = ~b8; INCF b8,1 ; b8++; ; RETURN ;} // 3 instructions, 4 cycles ; ;/*======================================================================*/ ;void negate8b (void) // INDF = -b8 ;/*======================================================================*/ ; ;{ negate8b COMF b8,W ; INDF = ~b8; MOVWF INDF INCF INDF,1 ; INDF++; ; RETURN ;} // 4 instructions, 5 cycles ; ;/*======================================================================*/ ;void negate16 (void) // r16 = -b16 ;/*======================================================================*/ ; ;{ negate16 COMF b16+1,W ; r16.high8 = ~b16.high8; MOVWF r16+1 COMF b16,W ; r16.low8 = ~b16.low8; MOVWF r16 INCFSZ r16,1 ; r16.low8 = incsz(r16.low8); RETURN ; return; INCF r16+1,1 ; r16.high8++; ; RETURN ;} // 8 instructions, min:7 max:9 cycles ; ;/*======================================================================*/ ;void negate16a (void) // b16 = -b16 ;/*======================================================================*/ ; ;{ negate16a COMF b16+1,1 ; b16.high8 = ~b16.high8; COMF b16,1 ; b16.low8 = ~b16.low8; INCFSZ b16,1 ; b16.low8 = incsz(b16.low8); RETURN ; return; INCF b16+1,1 ; b16.high8++; ; RETURN ;} // 6 instructions, min:5 max:7 cycles ; ;/*======================================================================*/ ;void negate16b (void) // INDF = -INDF ;/*======================================================================*/ ; ;{ negate16b COMF INDF,1 ; INDF = ~INDF; INCF FSR,1 ; FSR++; COMF INDF,1 ; INDF = ~INDF; DECF FSR,1 ; FSR--; INCFSZ INDF,1 ; INDF = incsz(INDF); RETURN ; return; INCF FSR,1 ; FSR++; INCF INDF,1 ; INDF++; ; RETURN ;} // 9 instructions, min:7 max:10 cycles ; ;/*======================================================================*/ ;void negate24 (void) // r24 = -b24 ;/*======================================================================*/ ; ;{ negate24 COMF b24+2,W ; r24.high8 = ~b24.high8; MOVWF r24+2 COMF b24+1,W ; r24.midL8 = ~b24.midL8; MOVWF r24+1 COMF b24,W ; r24.low8 = ~b24.low8; MOVWF r24 INCFSZ r24,1 ; r24.low8 = incsz(r24.low8); RETURN ; return; INCFSZ r24+1,1 ; r24.midL8 = incsz(r24.midL8); RETURN ; return; INCF r24+2,1 ; r24.high8++; ; RETURN ;} // 12 instructions, min:12 max:16 cycles ; ;/*======================================================================*/ ;void negate24a (void) // b24 = -b24 ;/*======================================================================*/ ; ;{ negate24a COMF b24+2,1 ; b24.high8 = ~b24.high8; COMF b24+1,1 ; b24.midL8 = ~b24.midL8; COMF b24,1 ; b24.low8 = ~b24.low8; ; INCFSZ b24,1 ; b24.low8 = incsz(b24.low8); RETURN ; return; INCFSZ b24+1,1 ; b24.midL8 = incsz(b24.midL8); RETURN ; return; INCF b24+2,1 ; b24.high8++; ; RETURN ;} // 9 instructions, min:6 max:10 cycles ; ;/*======================================================================*/ ;void negate24b (void) // INDF = -INDF ;/*======================================================================*/ ; ;{ negate24b MOVF FSR,W ; W = FSR; COMF INDF,1 ; INDF = ~INDF; INCF FSR,1 ; FSR++; COMF INDF,1 ; INDF = ~INDF; INCF FSR,1 ; FSR++; COMF INDF,1 ; INDF = ~INDF; MOVWF FSR ; FSR = W; ; INCFSZ INDF,1 ; INDF = incsz(INDF); RETURN ; return; INCF FSR,1 ; FSR++; INCFSZ INDF,1 ; INDF = incsz(INDF); RETURN ; return; INCF FSR,1 ; FSR++; INCF INDF,1 ; INDF++; ; RETURN ;} // 15 instructions, min:10 max:16 cycles ; ;/*======================================================================*/ ;void negate32 (void) // r32 = -b32 ;/*======================================================================*/ ; ;{ negate32 COMF b32+3,W ; r32.high8 = ~b32.high8; MOVWF r32+3 COMF b32+2,W ; r32.midH8 = ~b32.midH8; MOVWF r32+2 COMF b32+1,W ; r32.midL8 = ~b32.midL8; MOVWF r32+1 COMF b32,W ; r32.low8 = ~b32.low8; MOVWF r32 ; INCFSZ r32,1 ; r32.low8 = incsz(r32.low8); RETURN ; return; INCFSZ r32+1,1 ; r32.midL8 = incsz(r32.midL8); RETURN ; return; INCFSZ r32+2,1 ; r32.midH8 = incsz(r32.midH8); RETURN ; return; INCF r32+3,1 ; r32.high8++; ; RETURN ;} // 16 instructions, min:14 max:20 cycles ; ;/*======================================================================*/ ;void negate32a (void) // b32 = -b32 ;/*======================================================================*/ ; ;{ negate32a COMF b32+3,1 ; b32.high8 = ~b32.high8; COMF b32+2,1 ; b32.midH8 = ~b32.midH8; COMF b32+1,1 ; b32.midL8 = ~b32.midL8; COMF b32,1 ; b32.low8 = ~b32.low8; ; INCFSZ b32,1 ; b32.low8 = incsz(b32.low8); RETURN ; return; INCFSZ b32+1,1 ; b32.midL8 = incsz(b32.midL8); RETURN ; return; INCFSZ b32+2,1 ; b32.midH8 = incsz(b32.midH8); RETURN ; return; INCF b32+3,1 ; b32.high8++; ; RETURN ;} // 12 instructions, min:10 max:16 cycles ; ;/*======================================================================*/ ;void negate32b (void) // INDF = -b32 ;/*======================================================================*/ ; ;{ negate32b ; uns8 ww; ; MOVF FSR,W ; ww = FSR; MOVWF ww COMF b32,W ; INDF = ~b32.low8; MOVWF INDF INCF FSR,1 ; FSR++; COMF b32+1,W ; INDF = ~b32.midL8; MOVWF INDF INCF FSR,1 ; FSR++; COMF b32+2,W ; INDF = ~b32.midH8; MOVWF INDF INCF FSR,1 ; FSR++; COMF b32+3,W ; INDF = ~b32.high8; MOVWF INDF MOVF ww,W ; FSR = ww; MOVWF FSR ; INCFSZ INDF,1 ; INDF = incsz(INDF); RETURN ; return; INCF FSR,1 ; FSR++; INCFSZ INDF,1 ; INDF = incsz(INDF); RETURN ; return; INCF FSR,1 ; FSR++; INCFSZ INDF,1 ; INDF = incsz(INDF); RETURN ; return; INCF FSR,1 ; FSR++; INCF INDF,1 ; INDF++; ; RETURN ;} // 27 instructions, min:18 max:27 cycles ; ;/*======================================================================*/ ;void add8 (void) // r8 = a8 + b8 ;/*======================================================================*/ ; ;{ add8 MOVF b8,W ; W = b8; ADDWF a8,W ; W = a8 + W; MOVWF r8 ; r8 = W; ; RETURN ;} // 4 instructions, 5 cycles ; ;/*======================================================================*/ ;void add8a (void) // a8 += b8 ;/*======================================================================*/ ; ;{ add8a MOVF b8,W ; W = b8; ADDWF a8,1 ; a8 += W; ; RETURN ;} // 3 instructions, 4 cycles ; ;/*======================================================================*/ ;void add8b (void) // INDF += b8 ;/*======================================================================*/ ; ;{ add8b MOVF b8,W ; INDF += b8; ADDWF INDF,1 ; RETURN ;} // 3 instructions, 4 cycles ; ;/*======================================================================*/ ;void add16 (void) // r16 = a16 + b16 ;/*======================================================================*/ ; ;{ add16 MOVF b16,W ; r16.low8 = a16.low8 + b16.low8; ADDWF a16,W MOVWF r16 MOVF a16+1,W ; r16.high8 = a16.high8; MOVWF r16+1 ; MOVF b16+1,W ; W = b16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b16.high8); INCFSZ b16+1,W ADDWF r16+1,1 ; r16.high8 += W; ; RETURN ;} // 10 instructions, 11 cycles ; ;/*======================================================================*/ ;void add16a (void) // a16 += b16 ;/*======================================================================*/ ; ;{ add16a MOVF b16,W ; a16.low8 += b16.low8; ADDWF a16,1 ; MOVF b16+1,W ; W = b16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b16.high8); INCFSZ b16+1,W ADDWF a16+1,1 ; a16.high8 += W; ; RETURN ;} // 7 instructions, 8 cycles ; ;/*======================================================================*/ ;void add16b (void) // INDF += b16 ;/*======================================================================*/ ; ;{ add16b MOVF b16,W ; INDF += b16.low8; ADDWF INDF,1 INCF FSR,1 ; FSR++; MOVF b16+1,W ; W = b16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b16.high8); INCFSZ b16+1,W ADDWF INDF,1 ; INDF += W; ; RETURN ;} // 8 instructions, 9 cycles ; ;/*======================================================================*/ ;void add24 (void) // r24 = a24 + b24 ;/*======================================================================*/ ; ;{ add24 MOVF b24,W ; r24.low8 = a24.low8 + b24.low8; ADDWF a24,W MOVWF r24 ; MOVF a24+1,W ; r24.midL8 = a24.midL8; MOVWF r24+1 MOVF b24+1,W ; W = b24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b24.midL8); INCFSZ b24+1,W ADDWF r24+1,1 ; r24.midL8 += W; ; MOVF a24+2,W ; r24.high8 = a24.high8; MOVWF r24+2 MOVF b24+2,W ; W = b24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b24.high8); INCFSZ b24+2,W ADDWF r24+2,1 ; r24.high8 += W; ; RETURN ;} // 16 instructions, 17 cycles ; ;/*======================================================================*/ ;void add24a (void) // a24 += b24 ;/*======================================================================*/ ; ;{ add24a MOVF b24,W ; a24.low8 += b24.low8; ADDWF a24,1 ; MOVF b24+1,W ; W = b24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b24.midL8); INCFSZ b24+1,W ADDWF a16+1,1 ; a16.midL8 += W; ; MOVF b24+2,W ; W = b24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b24.high8); INCFSZ b24+2,W ADDWF a16+1,1 ; a16.high8 += W; ; RETURN ;} // 11 instructions, 12 cycles ; ;/*======================================================================*/ ;void add24b (void) // INDF += b24 ;/*======================================================================*/ ; ;{ add24b MOVF b24,W ; INDF += b24.low8; ADDWF INDF,1 INCF FSR,1 ; FSR++; ; MOVF b24+1,W ; W = b24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b24.midL8); INCFSZ b24+1,W ADDWF INDF,1 ; INDF += W; INCF FSR,1 ; FSR++; ; MOVF b24+2,W ; W = b24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b24.high8); INCFSZ b24+2,W ADDWF INDF,1 ; INDF += W; ; RETURN ;} // 13 instructions, 14 cycles ; ;/*======================================================================*/ ;void add32 (void) // r32 = a32 + b32 ;/*======================================================================*/ ; ;{ add32 MOVF b32,W ; r32.low8 = a32.low8 + b32.low8; ADDWF a32,W MOVWF r32 ; MOVF a32+1,W ; r32.midL8 = a32.midL8; MOVWF r32+1 MOVF b32+1,W ; W = b32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.midL8); INCFSZ b32+1,W ADDWF r32+1,1 ; r32.midL8 += W; ; MOVF a32+2,W ; r32.midH8 = a32.midH8; MOVWF r32+2 MOVF b32+2,W ; W = b32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.midH8); INCFSZ b32+2,W ADDWF r32+2,1 ; r32.midH8 += W; ; MOVF a32+3,W ; r32.high8 = a32.high8; MOVWF r32+3 MOVF b32+3,W ; W = b32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.high8); INCFSZ b32+3,W ADDWF r32+3,1 ; r32.high8 += W; ; RETURN ;} // 22 instructions, 23 cycles ; ;/*======================================================================*/ ;void add32a (void) // a32 += b32 ;/*======================================================================*/ ; ;{ add32a MOVF b32,W ; a32.low8 += b32.low8; ADDWF a32,1 ; MOVF b32+1,W ; W = b32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.midL8); INCFSZ b32+1,W ADDWF a32+1,1 ; a32.midL8 += W; ; MOVF b32+2,W ; W = b32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.midH8); INCFSZ b32+2,W ADDWF a32+2,1 ; a32.midH8 += W; ; MOVF b32+3,W ; W = b32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.high8); INCFSZ b32+3,W ADDWF a32+3,1 ; a32.high8 += W; ; RETURN ;} // 15 instructions, 16 cycles ; ;/*======================================================================*/ ;void add32b (void) // INDF += b32 ;/*======================================================================*/ ; ;{ add32b MOVF b32,W ; INDF += b32.low8; ADDWF INDF,1 INCF FSR,1 ; FSR++; ; MOVF b32+1,W ; W = b32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.midL8); INCFSZ b32+1,W ADDWF INDF,1 ; INDF += W; INCF FSR,1 ; FSR++; ; MOVF b32+2,W ; W = b32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.midH8); INCFSZ b32+2,W ADDWF INDF,1 ; INDF += W; INCF FSR,1 ; FSR++; ; MOVF b32+3,W ; W = b32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(b32.high8); INCFSZ b32+3,W ADDWF INDF,1 ; INDF += W; ; RETURN ;} // 18 instructions, 19 cycles ; ;/*======================================================================*/ ;void sub8 (void) // r8 = a8 - b8 ;/*======================================================================*/ ; ;{ sub8 MOVF b8,W ; r8 = a8 - b8; SUBWF a8,W MOVWF r8 ; RETURN ;} // 4 instructions, 5 cycles ; ;/*======================================================================*/ ;void sub8a (void) // a8 -= b8 ;/*======================================================================*/ ; ;{ sub8a ; MOVF b8,W ; a8 -= b8; SUBWF a8,1 ; RETURN ;} // 3 instructions, 4 cycles ; ;/*======================================================================*/ ;void sub8b (void) // INDF -= b8 ;/*======================================================================*/ ; ;{ sub8b ; MOVF b8,W ; INDF -= b8; SUBWF INDF,1 ; RETURN ;} // 3 instructions, 4 cycles ; ;/*======================================================================*/ ;void sub16 (void) // r16 = a16 - b16 ;/*======================================================================*/ ; ;{ sub16 MOVF b16,W ; r16.low8 = a16.low8 - b16.low8; SUBWF a16,W MOVWF r16 MOVF a16+1,W ; r16.high8 = a16.high8; MOVWF r16+1 ; MOVF b16+1,W ; W = b16.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b16.high8); INCFSZ b16+1,W SUBWF r16+1,1 ; r16.high8 -= W; ; RETURN ;} // 10 instructions, 11 cycles ; ;/*======================================================================*/ ;void sub16a (void) // a16 -= b16 ;/*======================================================================*/ ; ;{ sub16a MOVF b16,W ; a16.low8 -= b16.low8; SUBWF a16,1 ; MOVF b16+1,W ; W = b16.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b16.high8); INCFSZ b16+1,W SUBWF a16+1,1 ; a16.high8 -= W; ; RETURN ;} // 7 instructions, 8 cycles ; ;/*======================================================================*/ ;void sub16b (void) // INDF -= b16 ;/*======================================================================*/ ; ;{ sub16b MOVF b16,W ; INDF -= b16.low8; SUBWF INDF,1 INCF FSR,1 ; FSR++; MOVF b16+1,W ; W = b16.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b16.high8); INCFSZ b16+1,W SUBWF INDF,1 ; INDF -= W; ; RETURN ;} // 8 instructions, 9 cycles ; ;/*======================================================================*/ ;void sub24 (void) // r24 = a24 - b24 ;/*======================================================================*/ ; ;{ sub24 MOVF b24,W ; r24.low8 = a24.low8 - b24.low8; SUBWF a24,W MOVWF r24 ; MOVF a24+1,W ; r24.midL8 = a24.midL8; MOVWF r24+1 MOVF b24+1,W ; W = b24.midL8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b24.midL8); INCFSZ b24+1,W SUBWF r24+1,1 ; r24.midL8 -= W; ; MOVF a24+2,W ; r24.high8 = a24.high8; MOVWF r24+2 MOVF b24+2,W ; W = b24.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b24.high8); INCFSZ b24+2,W SUBWF r24+2,1 ; r24.high8 -= W; ; RETURN ;} // 16 instructions, 17 cycles ; ;/*======================================================================*/ ;void sub24a (void) // a24 -= b24 ;/*======================================================================*/ ; ;{ sub24a MOVF b24,W ; a24.low8 -= b24.low8; SUBWF a24,1 ; MOVF b24+1,W ; W = b24.midL8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b24.midL8); INCFSZ b24+1,W SUBWF a24+1,1 ; a24.midL8 -= W; ; MOVF b24+2,W ; W = b24.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b24.high8); INCFSZ b24+2,W SUBWF a24+2,1 ; a24.high8 -= W; ; RETURN ;} // 11 instructions, 12 cycles ; ;/*======================================================================*/ ;void sub24b (void) // INDF -= b24 ;/*======================================================================*/ ; ;{ sub24b MOVF b24,W ; INDF -= b24.low8; SUBWF INDF,1 INCF FSR,1 ; FSR++; ; MOVF b24+1,W ; W = b24.midL8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b24.midL8); INCFSZ b24+1,W SUBWF INDF,1 ; INDF -= W; INCF FSR,1 ; FSR++; ; MOVF b24+2,W ; W = b24.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b24.high8); INCFSZ b24+2,W SUBWF INDF,1 ; INDF -= W; ; RETURN ;} // 13 instructions, 14 cycles ; ;/*======================================================================*/ ;void sub32 (void) // r32 = a32 - b32 ;/*======================================================================*/ ; ;{ sub32 MOVF b32,W ; r32.low8 = a32.low8 - b32.low8; SUBWF a32,W MOVWF r32 ; MOVF a32+1,W ; r32.midL8 = a32.midL8; MOVWF r32+1 MOVF b32+1,W ; W = b32.midL8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.midL8); INCFSZ b32+1,W SUBWF r32+1,1 ; r32.midL8 -= W; ; MOVF a32+2,W ; r32.midH8 = a32.midH8; MOVWF r32+2 MOVF b32+2,W ; W = b32.midH8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.midH8); INCFSZ b32+2,W SUBWF r32+2,1 ; r32.midH8 -= W; ; MOVF a32+3,W ; r32.high8 = a32.high8; MOVWF r32+3 MOVF b32+3,W ; W = b32.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.high8); INCFSZ b32+3,W SUBWF r32+3,1 ; r32.high8 -= W; ; RETURN ;} // 22 instructions, 23 cycles ; ;/*======================================================================*/ ;void sub32a (void) // a32 -= b32 ;/*======================================================================*/ ; ;{ sub32a MOVF b32,W ; a32.low8 -= b32.low8; SUBWF a32,1 ; MOVF b32+1,W ; W = b32.midL8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.midL8); INCFSZ b32+1,W SUBWF a32+1,1 ; a32.midL8 -= W; ; MOVF b32+2,W ; W = b32.midH8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.midH8); INCFSZ b32+2,W SUBWF a32+2,1 ; a32.midH8 -= W; ; MOVF b32+3,W ; W = b32.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.high8); INCFSZ b32+3,W SUBWF a32+3,1 ; a32.high8 -= W; ; RETURN ;} // 15 instructions, 19 cycles ; ;/*======================================================================*/ ;void sub32b (void) // INDF -= b32 ;/*======================================================================*/ ; ;{ sub32b MOVF b32,W ; INDF -= b32.low8; SUBWF INDF,1 INCF FSR,1 ; FSR++; ; MOVF b32+1,W ; W = b32.midL8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.midL8); INCFSZ b32+1,W SUBWF INDF,1 ; INDF -= W; INCF FSR,1 ; FSR++; ; MOVF b32+2,W ; W = b32.midH8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.midH8); INCFSZ b32+2,W SUBWF INDF,1 ; INDF -= W; INCF FSR,1 ; FSR++; ; MOVF b32+3,W ; W = b32.high8; BTFSS 0x03,Carry ; if (!Carry) W = incsz(b32.high8); INCFSZ b32+3,W SUBWF INDF,1 ; INDF -= W; ; RETURN ;} // 18 instructions, 19 cycles ; ;/*======================================================================*/ ;void mpy8x8 (void) // r16 = a8 * b8 ;/*======================================================================*/ ; ;{ mpy8x8 ; uns8 ix; ; CLRF r16 ; r16 = 0; CLRF r16+1 MOVF b8,W ; W = b8; BTFSC 0x03,Zero_ ; if (W) GOTO m002 ; { MOVWF r16 ; r16.low8 = W; MOVLW .8 ; ix = 8; MOVWF ix MOVF a8,W ; W = a8; ; do ; { m001 BCF 0x03,Carry ; Carry = 0; BTFSC r16,0 ; if (r16.0) r16.high8 += W; ADDWF r16+1,1 RRF r16+1,1 ; r16.high8 = rr (r16.high8); RRF r16,1 ; r16.low8 = rr (r16.low8); ; } DECFSZ ix,1 ; while (--ix); GOTO m001 ; } m002 RETURN ;} // 17 instructions, min:11, max:77 cycles ; ;/*======================================================================*/ ;void mpy8x8a (void) // INDF = a8 * b8 ;/*======================================================================*/ ; ;{ mpy8x8a ; uns8 ix, m; ; CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; CLRF INDF ; INDF = 0; MOVF b8,W ; W = b8; BTFSC 0x03,Zero_ ; if (W) GOTO m004 ; { MOVWF m ; m = W; MOVLW .8 ; ix = 8; MOVWF ix_2 MOVF a8,W ; W = a8; ; do ; { m003 BCF 0x03,Carry ; Carry = 0; BTFSC m,0 ; if (m.0) INDF += W; ADDWF INDF,1 RRF INDF,1 ; INDF = rr (INDF); DECF FSR,1 ; FSR--; RRF INDF,1 ; INDF = rr (INDF); INCF FSR,1 ; FSR++; RRF m,1 ; m = rr (m); ; } DECFSZ ix_2,1 ; while (--ix); GOTO m003 ; } m004 RETURN ;} // 21 instructions, min:8, max:?? cycles ; ;/*======================================================================*/ ;void mpy16x8 (void) // r24 = a16 * b8 ;/*======================================================================*/ ; ;{ mpy16x8 ; uns8 ix; ; MOVF b8,W ; W = b8; BTFSS 0x03,Zero_ ; if (!W) GOTO m005 ; { CLRF r24+2 ; r24.high8 = 0; CLRF r24 ; r24.low16 = 0; CLRF r24+1 ; } GOTO m008 ; else ; { m005 XORLW .1 ; r24.low8 = W ^ 1; MOVWF r24 MOVF a16,W ; r24.high16 = a16; MOVWF r24+1 MOVF a16+1,W MOVWF r24+2 MOVLW .8 ; ix = 8; MOVWF ix_3 ; do ; { m006 RRF r24,W ; W = rr(r24.low8); BTFSS 0x03,Carry ; if (Carry) GOTO m007 ; { MOVF a16,W ; r24.midL8 += a16.low8; ADDWF r24+1,1 MOVF a16+1,W ; W = a16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a16.high8); INCFSZ a16+1,W ADDWF r24+2,1 ; r24.high8 += W; ; } m007 RRF r24+2,1 ; r24.high8 = rr(r24.high8); RRF r24+1,1 ; r24.midL8 = rr(r24.midL8); RRF r24,1 ; r24.low8 = rr(r24.low8); ; } DECFSZ ix_3,1 ; while (--ix); GOTO m006 ; } m008 RETURN ;} // 30 instructions, min:10, max:131 cycles ; ;/*======================================================================*/ ;void mpy16x8a (void) // INDF = a16 * b8 ;/*======================================================================*/ ; ;{ mpy16x8a ; uns8 ix, m; ; CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 1 CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 2 CLRF INDF ; INDF = 0; MOVF b8,W ; W = b8; BTFSC 0x03,Zero_ ; if (W) GOTO m011 ; { MOVWF m_2 ; m = W; DECF FSR,1 ; FSR--; // 1 MOVLW .8 ; ix = 8; MOVWF ix_4 ; do ; { m009 BCF 0x03,Carry ; Carry = 0; BTFSS m_2,0 ; if (m.0) GOTO m010 ; { MOVF a16,W ; INDF += a16.low8; ADDWF INDF,1 INCF FSR,1 ; FSR++; // 2 MOVF a16+1,W ; W = a16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a16.high8); INCFSZ a16+1,W ADDWF INDF,1 ; INDF += W; DECF FSR,1 ; FSR--; // 1 ; } m010 INCF FSR,1 ; FSR++; // 2 RRF INDF,1 ; INDF = rr(INDF); DECF FSR,1 ; FSR--; // 1 RRF INDF,1 ; INDF = rr(INDF); DECF FSR,1 ; FSR--; // 0 RRF INDF,1 ; INDF = rr(INDF); INCF FSR,1 ; FSR++; // 1 RRF m_2,1 ; m = rr(m); ; } DECFSZ ix_4,1 ; while (--ix); GOTO m009 ; } m011 RETURN ;} // 34 instructions, min:??, max:??? cycles ; ;/*======================================================================*/ ;void mpy24x8 (void) // r32 = a24 * b8 ;/*======================================================================*/ ; ;{ mpy24x8 ; uns8 ix; ; MOVF b8,W ; W = b8; BTFSS 0x03,Zero_ ; if (!W) GOTO m012 ; { CLRF r32+2 ; r32.high16 = 0; CLRF r32+3 CLRF r32 ; r32.low16 = 0; CLRF r32+1 ; } GOTO m015 ; else ; { m012 XORLW .1 ; r32.low8 = W ^ 1; MOVWF r32 MOVF a24,W ; r32.midL8 = a24.low8; MOVWF r32+1 MOVF a24+1,W ; r32.high16 = a24.high16; MOVWF r32+2 MOVF a24+2,W MOVWF r32+3 MOVLW .8 ; ix = 8; MOVWF ix_5 ; do ; { m013 RRF r32,W ; W = rr(r32.low8); BTFSS 0x03,Carry ; if (Carry) GOTO m014 ; { MOVF a24,W ; r32.midL8 += a24.low8; ADDWF r32+1,1 MOVF a24+1,W ; W = a24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.midL8); INCFSZ a24+1,W ADDWF r32+2,1 ; r32.midH8 += W; MOVF a24+2,W ; W = a24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.high8); INCFSZ a24+2,W ADDWF r32+3,1 ; r32.high8 += W; ; } m014 RRF r32+3,1 ; r32.high8 = rr(r32.high8); RRF r32+2,1 ; r32.midH8 = rr(r32.midH8); RRF r32+1,1 ; r32.midL8 = rr(r32.midL8); RRF r32,1 ; r32.low8 = rr(r32.low8); ; } DECFSZ ix_5,1 ; while (--ix); GOTO m013 ; } m015 RETURN ;} // 38 instructions, min:14, max:169 cycles ; ;/*======================================================================*/ ;void mpy24x8a (void) // INDF = a24 * b8 ;/*======================================================================*/ ; ;{ mpy24x8a ; uns8 ix, m, p; ; CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 1 CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 2 CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 3 CLRF INDF ; INDF = 0; ; MOVF b8,W ; W = b8; BTFSC 0x03,Zero_ ; if (W) GOTO m018 ; { MOVWF m_3 ; m = W; MOVLW .8 ; ix = 8; MOVWF ix_6 MOVF FSR,W ; p = FSR; MOVWF p DECF FSR,1 ; FSR--; // 2 DECF FSR,1 ; FSR--; // 1 ; do ; { m016 RRF m_3,W ; W = rr(m); BTFSS 0x03,Carry ; if (Carry) GOTO m017 ; { MOVF a24,W ; INDF += a24.low8; ADDWF INDF,1 INCF FSR,1 ; FSR++; // 2 MOVF a24+1,W ; W = a24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.midL8); INCFSZ a24+1,W ADDWF INDF,1 ; INDF += W; INCF FSR,1 ; FSR++; // 3 MOVF a24+2,W ; W = a24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.high8); INCFSZ a24+2,W ADDWF INDF,1 ; INDF += W; ; } // else !Carry m017 MOVF p,W ; FSR = p; MOVWF FSR RRF INDF,1 ; INDF = rr(INDF); DECF FSR,1 ; FSR--; // 2 RRF INDF,1 ; INDF = rr(INDF); DECF FSR,1 ; FSR--; // 1 RRF INDF,1 ; INDF = rr(INDF); DECF FSR,1 ; FSR--; // 0 RRF INDF,1 ; INDF = rr(INDF); INCF FSR,1 ; FSR++; // 1 RRF m_3,1 ; m = rr(m); ; } DECFSZ ix_6,1 ; while (--ix); GOTO m016 ; } m018 RETURN ;} // 46 instructions, min:13, max:??? cycles ; ;/*======================================================================*/ ;void mpy32x8 (void) // r40 = a32 * b8 ;/*======================================================================*/ ; ;{ mpy32x8 ; uns8 ix; ; MOVF b8,W ; W = b8; BTFSS 0x03,Zero_ ; if (!W) GOTO m019 ; { CLRF r40+4 ; r40[4] = 0; CLRF r40+3 ; r40[3] = 0; CLRF r40+2 ; r40[2] = 0; CLRF r40+1 ; r40[1] = 0; CLRF r40 ; r40[0] = 0; ; } GOTO m022 ; else ; { m019 MOVF a32+3,W ; r40[0] = a32.high8; MOVWF r40 MOVF a32+2,W ; r40[1] = a32.midH8; MOVWF r40+1 MOVF a32+1,W ; r40[2] = a32.midL8; MOVWF r40+2 MOVF a32,W ; r40[3] = a32.low8; MOVWF r40+3 MOVLW .1 ; r40[4] = b8 ^ 1; XORWF b8,W MOVWF r40+4 MOVLW .8 ; ix = 8; MOVWF ix_7 ; do ; { m020 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r40+4,0 ; if (r40[4].0) GOTO m021 ; { MOVF a32,W ; r40[3] += a32.low8; ADDWF r40+3,1 ; MOVF a32+1,W ; W = a32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midL8); INCFSZ a32+1,W ADDWF r40+2,1 ; r40[2] += W; ; MOVF a32+2,W ; W = a32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midH8); INCFSZ a32+2,W ADDWF r40+1,1 ; r40[1] += W; ; MOVF a32+3,W ; W = a32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.high8); INCFSZ a32+3,W ADDWF r40,1 ; r40[0] += W; ; } ; } ;#asm m021 RRF r40,1 ; rrf r40+0,F ; r40[0] = rr(r40[0]); RRF r40+1,1 ; rrf r40+1,F ; r40[1] = rr(r40[1]); RRF r40+2,1 ; rrf r40+2,F ; r40[2] = rr(r40[2]); RRF r40+3,1 ; rrf r40+3,F ; r40[3] = rr(r40[3]); RRF r40+4,1 ; rrf r40+4,F ; r40[4] = rr(r40[4]); ;#endasm ; } DECFSZ ix_7,1 ; while (--ix); GOTO m020 ; } m022 RETURN ;} // 47 instructions, min:15, max:208 cycles ; ;/*======================================================================*/ ;void mpy32x8a (void) // INDF = a32 * b8 ;/*======================================================================*/ ; ;{ mpy32x8a ; uns8 ix, m, p; ; CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 1 CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 2 CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 3 CLRF INDF ; INDF = 0; INCF FSR,1 ; FSR++; // 4 CLRF INDF ; INDF = 0; ; MOVF b8,W ; W = b8; BTFSC 0x03,Zero_ ; if (W) GOTO m025 ; { MOVWF m_4 ; m = W; MOVLW .8 ; ix = 8; MOVWF ix_8 MOVF FSR,W ; p = FSR; MOVWF p_2 DECF FSR,1 ; FSR--; // 3 DECF FSR,1 ; FSR--; // 2 DECF FSR,1 ; FSR--; // 1 ; do ; { m023 RRF m_4,W ; W = rr(m); ; { BTFSS 0x03,Carry ; if (Carry) GOTO m024 ; { MOVF a32,W ; INDF += a32.low8; ADDWF INDF,1 INCF FSR,1 ; FSR++; // 2 MOVF a32+1,W ; W = a32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midL8); INCFSZ a32+1,W ADDWF INDF,1 ; INDF += W; INCF FSR,1 ; FSR++; // 3 MOVF a32+2,W ; W = a32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midH8); INCFSZ a32+2,W ADDWF INDF,1 ; INDF += W; INCF FSR,1 ; FSR++; // 4 MOVF a32+3,W ; W = a32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.high8); INCFSZ a32+3,W ADDWF INDF,1 ; INDF += W; ; } ; } // else !Carry m024 MOVF p_2,W ; FSR = p; // 4 MOVWF FSR ;#asm RRF INDF,1 ; rrf INDF,F DECF FSR,1 ; decf FSR,f ; 3 RRF INDF,1 ; rrf INDF,F DECF FSR,1 ; decf FSR,f ; 2 RRF INDF,1 ; rrf INDF,F DECF FSR,1 ; decf FSR,f ; 1 RRF INDF,1 ; rrf INDF,F DECF FSR,1 ; decf FSR,f ; 0 RRF INDF,1 ; rrf INDF,F INCF FSR,1 ; incf FSR,f ; 1 ;#endasm ; } DECFSZ ix_8,1 ; while (--ix); GOTO m023 ; } m025 RETURN ;} // 55 instructions, min:15, max:??? cycles ; ;/*======================================================================*/ ;void mpy16x16 (void) // r32 = a16 * b16 ;/*======================================================================*/ ; ;{ mpy16x16 ; uns8 ix; // temporary ; MOVF b16,W ; if (!b16) IORWF b16+1,W BTFSS 0x03,Zero_ GOTO m026 ; { CLRF r32+2 ; r32.high16 = 0; CLRF r32+3 CLRF r32 ; r32.low16 = 0; CLRF r32+1 ; } GOTO m029 ; else ; { m026 MOVF a16,W ; r32.high16 = a16; MOVWF r32+2 MOVF a16+1,W MOVWF r32+3 MOVF b16+1,W ; r32.midL8 = b16.high8; MOVWF r32+1 MOVLW .1 ; r32.low8 = b16.low8 ^ 1; XORWF b16,W MOVWF r32 MOVLW .16 ; ix = 16; MOVWF ix_9 ; do ; { m027 BCF 0x03,Carry ; Carry = 0; BTFSS r32,0 ; if (r32.0) GOTO m028 ; { MOVF a16,W ; r32.midH8 += a16.low8; ADDWF r32+2,1 MOVF b16+1,W ; W = b16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a16.high8); INCFSZ a16+1,W ADDWF r32+3,1 ; r32.high8 += W; ; } m028 RRF r32+3,1 ; r32.high8 = rr(r32.high8); RRF r32+2,1 ; r32.midH8 = rr(r32.midH8); RRF r32+1,1 ; r32.midL8 = rr(r32.midL8); RRF r32,1 ; r32.low8 = rr(r32.low8); ; } DECFSZ ix_9,1 ; while (--ix); GOTO m027 ; } m029 RETURN ;} // 36 instructions, min:15, max:271 cycles ; ;/*======================================================================*/ ;void mpy16x16a (void) // r32 = a16 * b16 ;/*======================================================================*/ ; ;{ mpy16x16a ; uns8 ix; // temporary ; CLRF r32+2 ; r32.high16 = 0; CLRF r32+3 CLRF r32 ; r32.low16 = 0; CLRF r32+1 MOVF b16,W ; if (b16) IORWF b16+1,W BTFSC 0x03,Zero_ GOTO m032 ; { MOVF b16,W ; r32.low16 = b16; MOVWF r32 MOVF b16+1,W MOVWF r32+1 MOVLW .16 ; ix = 16; MOVWF ix_10 ; do ; { m030 RRF r32,W ; W = rr(r32.low8); BTFSS 0x03,Carry ; if (Carry) GOTO m031 ; { MOVF a16,W ; r32.midH8 += a16.low8; ADDWF r32+2,1 MOVF b16+1,W ; W = b16.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a16.high8); INCFSZ a16+1,W ADDWF r32+3,1 ; r32.high8 += W; ; } m031 RRF r32+3,1 ; r32.high8 = rr(r32.high8); RRF r32+2,1 ; r32.midH8 = rr(r32.midH8); RRF r32+1,1 ; r32.midL8 = rr(r32.midL8); RRF r32,1 ; r32.low8 = rr(r32.low8); ; } DECFSZ ix_10,1 ; while (--ix); GOTO m030 ; } m032 RETURN ;} // 30 instructions, min:14, max:274 cycles ; ;/*======================================================================*/ ;void mpy24x16 (void) // r40 = a24 * b16 ;/*======================================================================*/ ; ;{ mpy24x16 ; uns8 ix; // temporary ; MOVF b16,W ; if (!b16) IORWF b16+1,W BTFSS 0x03,Zero_ GOTO m033 ; { CLRF r40+4 ; r40[4] = 0; CLRF r40+3 ; r40[3] = 0; CLRF r40+2 ; r40[2] = 0; CLRF r40+1 ; r40[1] = 0; CLRF r40 ; r40[0] = 0; ; } GOTO m036 ; else ; { m033 MOVF a24+2,W ; r40[0] = a24.high8; MOVWF r40 MOVF a24+1,W ; r40[1] = a24.midL8; MOVWF r40+1 MOVF a24,W ; r40[2] = a24.low8; MOVWF r40+2 MOVF b16+1,W ; r40[3] = b16.high8; MOVWF r40+3 MOVLW .1 ; r40[4] = b16.low8 ^ 1; XORWF b16,W MOVWF r40+4 MOVLW .16 ; ix = 16; MOVWF ix_11 ; do ; { m034 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r40+4,0 ; if (r40[4].0) GOTO m035 ; { MOVF a24,W ; r40[2] += a24.low8; ADDWF r40+2,1 ; MOVF a24+1,W ; W = a24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.midL8); INCFSZ a24+1,W ADDWF r40+1,1 ; r40[1] += W; ; MOVF a24+2,W ; W = a24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.high8); INCFSZ a24+2,W ADDWF r40,1 ; r40[0] += W; ; } ; } ;#asm m035 RRF r40,1 ; rrf r40+0,F ; r40[0] = rr(r40[0]); RRF r40+1,1 ; rrf r40+1,F ; r40[1] = rr(r40[1]); RRF r40+2,1 ; rrf r40+2,F ; r40[2] = rr(r40[2]); RRF r40+3,1 ; rrf r40+3,F ; r40[3] = rr(r40[3]); RRF r40+4,1 ; rrf r40+4,F ; r40[4] = rr(r40[4]); ;#endasm ; } DECFSZ ix_11,1 ; while (--ix); GOTO m034 ; } m036 RETURN ;} // 44 instructions, min:16, max:349 cycles ; ;/*======================================================================*/ ;void mpy24x16a (void) // r40 = a24 * b16 ;/*======================================================================*/ ; ;{ mpy24x16a ; uns8 ix; // temporary ; CLRF r40+4 ; r40[4] = 0; CLRF r40+3 ; r40[3] = 0; CLRF r40+2 ; r40[2] = 0; CLRF r40+1 ; r40[1] = 0; CLRF r40 ; r40[0] = 0; MOVF b16,W ; if (b16) IORWF b16+1,W BTFSC 0x03,Zero_ GOTO m039 ; { MOVF b16+1,W ; r40[3] = b16.high8; MOVWF r40+3 MOVLW .1 ; r40[4] = b16.low8 ^ 1; XORWF b16,W MOVWF r40+4 MOVLW .16 ; ix = 16; MOVWF ix_12 ; do ; { m037 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r40+4,0 ; if (r40[4].0) GOTO m038 ; { MOVF a24,W ; r40[2] += a24.low8; ADDWF r40+2,1 ; MOVF a24+1,W ; W = a24.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.midL8); INCFSZ a24+1,W ADDWF r40+1,1 ; r40[1] += W; ; MOVF a24+2,W ; W = a24.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a24.high8); INCFSZ a24+2,W ADDWF r40,1 ; r40[0] += W; ; } ; } ;#asm m038 RRF r40,1 ; rrf r40+0,F ; r40[0] = rr(r40[0]); RRF r40+1,1 ; rrf r40+1,F ; r40[1] = rr(r40[1]); RRF r40+2,1 ; rrf r40+2,F ; r40[2] = rr(r40[2]); RRF r40+3,1 ; rrf r40+3,F ; r40[3] = rr(r40[3]); RRF r40+4,1 ; rrf r40+4,F ; r40[4] = rr(r40[4]); ;#endasm ; } DECFSZ ix_12,1 ; while (--ix); GOTO m037 ; } m039 RETURN ;} // ?? instructions, min:15, max:347 cycles ; ;/*======================================================================*/ ;void mpy32x16 (void) // r48 = a32 * b16 ;/*======================================================================*/ ; ;{ mpy32x16 ; uns8 ix; ; MOVF b16,W ; if (!b16) IORWF b16+1,W BTFSS 0x03,Zero_ GOTO m040 ; { CLRF r48 ; r48[0] = 0; CLRF r48+1 ; r48[1] = 0; CLRF r48+2 ; r48[2] = 0; CLRF r48+3 ; r48[3] = 0; CLRF r48+4 ; r48[4] = 0; CLRF r48+5 ; r48[5] = 0; ; } GOTO m043 ; else ; { m040 MOVF a32+3,W ; r48[0] = a32.high8; MOVWF r48 MOVF a32+2,W ; r48[1] = a32.midH8; MOVWF r48+1 MOVF a32+1,W ; r48[2] = a32.midL8; MOVWF r48+2 MOVF a32,W ; r48[3] = a32.low8; MOVWF r48+3 MOVF b16+1,W ; r48[4] = b16.high8; MOVWF r48+4 MOVLW .1 ; r48[5] = b16.low8 ^ 1; XORWF b16,W MOVWF r48+5 MOVLW .16 ; ix = 16; MOVWF ix_13 ; do ; { m041 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r48+5,0 ; if (r48[5].0) GOTO m042 ; { MOVF a32,W ; r48[3] += a32.low8; ADDWF r48+3,1 ; MOVF a32+1,W ; W = a32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midL8); INCFSZ a32+1,W ADDWF r48+2,1 ; r48[2] += W; ; MOVF a32+2,W ; W = a32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midH8); INCFSZ a32+2,W ADDWF r48+1,1 ; r48[1] += W; ; MOVF a32+3,W ; W = a32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.high8); INCFSZ a32+3,W ADDWF r48,1 ; r48[0] += W; ; } ; } ;#asm m042 RRF r48,1 ; rrf r48+0,F ; r48[0] = rr(r48[0]); RRF r48+1,1 ; rrf r48+1,F ; r48[1] = rr(r48[1]); RRF r48+2,1 ; rrf r48+2,F ; r48[2] = rr(r48[2]); RRF r48+3,1 ; rrf r48+3,F ; r48[3] = rr(r48[3]); RRF r48+4,1 ; rrf r48+4,F ; r48[4] = rr(r48[4]); RRF r48+5,1 ; rrf r48+5,F ; r48[5] = rr(r48[5]); ;#endasm ; } DECFSZ ix_13,1 ; while (--ix); GOTO m041 ; } m043 RETURN ;} // 52 instructions, min:17, max:427 cycles ; ;/*======================================================================*/ ;void mpy32x16a (void) // r48 = a32 * b16 ;/*======================================================================*/ ; ;{ mpy32x16a ; ; uns8 ix; ; CLRF r48 ; r48[0] = 0; CLRF r48+1 ; r48[1] = 0; CLRF r48+2 ; r48[2] = 0; CLRF r48+3 ; r48[3] = 0; CLRF r48+4 ; r48[4] = 0; CLRF r48+5 ; r48[5] = 0; MOVF b16,W ; if (b16) IORWF b16+1,W BTFSC 0x03,Zero_ GOTO m046 ; { MOVF b16+1,W ; r48[4] = b16.high8; MOVWF r48+4 MOVF b16,W ; r48[5] = b16.low8; MOVWF r48+5 MOVLW .16 ; ix = 16; MOVWF ix_14 ; do ; { m044 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r48+5,0 ; if (r48[5].0) GOTO m045 ; { MOVF a32,W ; r48[3] += a32.low8; ADDWF r48+3,1 ; MOVF a32+1,W ; W = a32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midL8); INCFSZ a32+1,W ADDWF r48+2,1 ; r48[2] += W; ; MOVF a32+2,W ; W = a32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midH8); INCFSZ a32+2,W ADDWF r48+1,1 ; r48[1] += W; ; MOVF a32+3,W ; W = a32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.high8); INCFSZ a32+3,W ADDWF r48,1 ; r48[0] += W; ; } ; } ;#asm m045 RRF r48,1 ; rrf r48+0,F ; r48[0] = rr(r48[0]); RRF r48+1,1 ; rrf r48+1,F ; r48[1] = rr(r48[1]); RRF r48+2,1 ; rrf r48+2,F ; r48[2] = rr(r48[2]); RRF r48+3,1 ; rrf r48+3,F ; r48[3] = rr(r48[3]); RRF r48+4,1 ; rrf r48+4,F ; r48[4] = rr(r48[4]); RRF r48+5,1 ; rrf r48+5,F ; r48[5] = rr(r48[5]); ;#endasm ; } DECFSZ ix_14,1 ; while (--ix); GOTO m044 ; } ; m046 RETURN ;} // 42 instructions, min:16, max:436 cycles ; ;/*======================================================================*/ ;void mpy32x32 (void) // r64 = a32 * b32 ;/*======================================================================*/ ; ;{ mpy32x32 ; ; uns8 ix; ; MOVF b32+2,W ; W = b32.high8 | b32.midH8; IORWF b32+3,W IORWF b32+1,W ; W = b32.midL8 | W; IORWF b32,W ; W = b32.low8 | W; BTFSS 0x03,Zero_ ; if (Zero_) GOTO m047 ; { CLRF r64 ; r64[0] = 0; CLRF r64+1 ; r64[1] = 0; CLRF r64+2 ; r64[2] = 0; CLRF r64+3 ; r64[3] = 0; CLRF r64+4 ; r64[4] = 0; CLRF r64+5 ; r64[5] = 0; CLRF r64+6 ; r64[6] = 0; CLRF r64+7 ; r64[7] = 0; ; } GOTO m050 ; else ; { m047 MOVF a32+3,W ; r64[0] = a32.high8; MOVWF r64 MOVF a32+2,W ; r64[1] = a32.midH8; MOVWF r64+1 MOVF a32+1,W ; r64[2] = a32.midL8; MOVWF r64+2 MOVF a32,W ; r64[3] = a32.low8; MOVWF r64+3 MOVF b32+3,W ; r64[4] = b32.high8; MOVWF r64+4 MOVF b32+2,W ; r64[5] = b32.midH8; MOVWF r64+5 MOVF b32+1,W ; r64[6] = b32.midL8; MOVWF r64+6 MOVLW .1 ; r64[7] = b32.low8 ^ 1; XORWF b32,W MOVWF r64+7 MOVLW .32 ; ix = 32; MOVWF ix_15 ; do ; { m048 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r64+7,0 ; if (r64[7].0) GOTO m049 ; { MOVF a32,W ; r64[3] += a32.low8; ADDWF r64+3,1 ; MOVF a32+1,W ; W = a32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midL8); INCFSZ a32+1,W ADDWF r64+2,1 ; r64[2] += W; ; MOVF a32+2,W ; W = a32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midH8); INCFSZ a32+2,W ADDWF r64+1,1 ; r64[1] += W; ; MOVF a32+3,W ; W = a32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.high8); INCFSZ a32+3,W ADDWF r64,1 ; r64[0] += W; ; } ; } ;#asm m049 RRF r64,1 ; rrf r64+0,F // r64[0] = rr(r64[0]); RRF r64+1,1 ; rrf r64+1,F // r64[1] = rr(r64[1]); RRF r64+2,1 ; rrf r64+2,F // r64[2] = rr(r64[2]); RRF r64+3,1 ; rrf r64+3,F // r64[3] = rr(r64[3]); RRF r64+4,1 ; rrf r64+4,F // r64[4] = rr(r64[4]); RRF r64+5,1 ; rrf r64+5,F // r64[5] = rr(r64[5]); RRF r64+6,1 ; rrf r64+6,F // r64[6] = rr(r64[6]); RRF r64+7,1 ; rrf r64+7,F // r64[7] = rr(r64[7]); ;#endasm ; } DECFSZ ix_15,1 ; while (--ix); GOTO m048 ; } ; m050 RETURN ;} // 62 instructions, min:21, max:913 cycles ; ;/*======================================================================*/ ;void mpy32x32a (void) // r64 = a32 * b32 ;/*======================================================================*/ ; ;{ mpy32x32a ; ; uns8 ix; ; CLRF r64 ; r64[0] = 0; CLRF r64+1 ; r64[1] = 0; CLRF r64+2 ; r64[2] = 0; CLRF r64+3 ; r64[3] = 0; CLRF r64+4 ; r64[4] = 0; CLRF r64+5 ; r64[5] = 0; CLRF r64+6 ; r64[6] = 0; CLRF r64+7 ; r64[7] = 0; ; MOVF b32+2,W ; W = b32.high8 | b32.midH8; IORWF b32+3,W IORWF b32+1,W ; W = b32.midL8 | W; IORWF b32,W ; W = b32.low8 | W; BTFSC 0x03,Zero_ ; if (!Zero_) GOTO m053 ; { MOVF b32+3,W ; r64[4] = b32.high8; MOVWF r64+4 MOVF b32+2,W ; r64[5] = b32.midH8; MOVWF r64+5 MOVF b32+1,W ; r64[6] = b32.midL8; MOVWF r64+6 MOVF b32,W ; r64[7] = b32.low8; MOVWF r64+7 MOVLW .32 ; ix = 32; MOVWF ix_16 ; do ; { m051 BCF 0x03,Carry ; Carry = 0; ; { BTFSS r64+7,0 ; if (r64[7].0) GOTO m052 ; { MOVF a32,W ; r64[3] += a32.low8; ADDWF r64+3,1 ; MOVF a32+1,W ; W = a32.midL8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midL8); INCFSZ a32+1,W ADDWF r64+2,1 ; r64[2] += W; ; MOVF a32+2,W ; W = a32.midH8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.midH8); INCFSZ a32+2,W ADDWF r64+1,1 ; r64[1] += W; ; MOVF a32+3,W ; W = a32.high8; BTFSC 0x03,Carry ; if (Carry) W = incsz(a32.high8); INCFSZ a32+3,W ADDWF r64,1 ; r64[0] += W; ; } ; } ;#asm m052 RRF r64,1 ; rrf r64+0,F // r64[0] = rr(r64[0]); RRF r64+1,1 ; rrf r64+1,F // r64[1] = rr(r64[1]); RRF r64+2,1 ; rrf r64+2,F // r64[2] = rr(r64[2]); RRF r64+3,1 ; rrf r64+3,F // r64[3] = rr(r64[3]); RRF r64+4,1 ; rrf r64+4,F // r64[4] = rr(r64[4]); RRF r64+5,1 ; rrf r64+5,F // r64[5] = rr(r64[5]); RRF r64+6,1 ; rrf r64+6,F // r64[6] = rr(r64[6]); RRF r64+7,1 ; rrf r64+7,F // r64[7] = rr(r64[7]); ;#endasm ; } DECFSZ ix_16,1 ; while (--ix); GOTO m051 ; } ; m053 RETURN ;} // 52 instructions, min:20, max:924 cycles ; ;/*======================================================================*/ ;void div16x8 (void) // q8,r8 = a16 / b8 ;/*======================================================================*/ ; ;{ div16x8 ; char ix, oldCy; ; BSF 0x53,ZeroDiv ;ZeroDiv = 1; MOVF b8,W ; W = b8; BTFSC 0x03,Zero_ ; if (!Zero_) GOTO m058 ; { BSF 0x53,Overflow ;Overflow = 1; // assume error SUBWF a16+1,W ; if (a16.high8