; CC1B Ver 0.5A beta, Copyright (c) B Knudsen Data ; C compiler for the Ubicom SX family ; ************ 24. Jun 2002 11:40 ************* device SX28 FSR EQU $04 Carry EQU 0 Zero_ EQU 2 FpFlags EQU $1A FpOverflow EQU 1 FpUnderFlow EQU 2 FpDiv0 EQU 3 FpRounding EQU 6 arg1f24 EQU $10 arg2f24 EQU $13 aarg EQU $16 sign EQU $18 counter EQU $19 aarg_2 EQU $16 sign_2 EQU $18 counter_2 EQU $19 xtra EQU $16 temp EQU $17 expo EQU $18 sign_3 EQU $19 expo_2 EQU $16 sign_4 EQU $17 rval EQU $10 sign_6 EQU $16 expo_4 EQU $17 xtra_2 EQU $18 rval_3 EQU $10 ad_data EQU $1B tx EQU $30 av EQU $33 mg EQU $36 a EQU $39 vx EQU $3C prev EQU $50 kp EQU $53 ORG $0200 _float24ToInt24 JMP m056 _int24ToFloat24 JMP m048 ORG $0000 ; FILE sx\demo-fpm.c ; ;#pragma chip SX28 // select device ; ;// FIRST ADD THE INTERRUPT ROUTINE (if any) ;// #include "app-int.c" ; ;#if _SX48 || _SX52 ; // locate library routine in code page 2 instead og code page 1 ; page2 float24 operator* _fmul24( float24 arg1f24, float24 arg2f24); ;#endif ; ;#pragma rambank 0 ;#pragma codepage 1 ORG $0202 ; FILE test\math24f.h ;// ************************************************* ;// 24 bit basic floating point math operations ;// Copyright (c) B Knudsen Data, Norway, 2000 - 2001 ;// ************************************************* ; ;#pragma library 1 ;/* PROTOTYPES for page definition in application header file: ;float24 operator* _fmul24( float24 arg1f24, float24 arg2f24); ;float24 operator/ _fdiv24( float24 arg1f24, float24 arg2f24); ;float24 operator+ _fadd24( float24 arg1f24, float24 arg2f24); ;float24 operator- _fsub24( float24 arg1f24, float24 arg2f24); ;float24 operator= _int24ToFloat24( int24 arg1f24); ;float24 operator= _int32ToFloat24( int32 arg32); ;int24 operator= _float24ToInt24( float24 arg1f24); ;bit operator< _f24_LT_f24( float24 arg1f24, float24 arg2f24); ;bit operator>= _f24_GE_f24( float24 arg1f24, float24 arg2f24); ;bit operator> _f24_GT_f24( float24 arg1f24, float24 arg2f24); ;bit operator<= _f24_LE_f24( float24 arg1f24, float24 arg2f24); ;*/ ; ;// DEFINABLE SYMBOLS (in the application code): ;//#define FP_OPTIM_SPEED // optimize for SPEED: default ;//#define FP_OPTIM_SIZE // optimize for SIZE ;//#define DISABLE_ROUNDING // disable rounding and save code space ; ;#define float24ToIEEE754(a) { a.mid8=rl(a.mid8); a.high8=rr(a.high8);\ ; a.mid8=rr(a.mid8); } ;#define IEEE754ToFloat24(a) { a.mid8=rl(a.mid8); a.high8=rl(a.high8);\ ; a.mid8=rr(a.mid8); } ; ; ;/* 24 bit floating point format: ; ; address ID ; X a.low8 : LSB, bit 0-7 of mantissa ; X+1 a.mid8 : bit 8-14 of mantissa, bit 15 is the sign bit ; X+2 a.high8 : MSB, bit 0-7 of exponent, with bias 0x7F ; ; bit 15 of mantissa is a hidden bit, always equal to 1 ; zero (0.0) : a.high8 = 0 (mantissa & sign ignored) ; ; MSB LSB ; 7F 00 00 : 1.0 = 1.0 * 2**(0x7F-0x7F) = 1.0 * 1 ; 7F 80 00 : -1.0 = -1.0 * 2**(0x7F-0x7F) = -1.0 * 1 ; 80 00 00 : 2.0 = 1.0 * 2**(0x80-0x7F) = 1.0 * 2 ; 80 40 00 : 3.0 = 1.5 * 2**(0x80-0x7F) = 1.5 * 2 ; 7E 60 00 : 0.875 = 1.75 * 2**(0x7E-0x7F) = 1.75 * 0.5 ; 7F 60 00 : 1.75 = 1.75 * 2**(0x7E-0x7F) = 1.75 * 1 ; 7F 7F FF : 1.999969482 ; 00 7C 5A : 0.0 (mantissa & sign ignored) ; 01 00 00 : 1.17549435e-38 = 1.0 * 2**(0x01-0x7F) ; FE 7F FF : 3.40277175e+38 = 1.999969482 * 2**(0xFE-0x7F) ; FF 00 00 : +INF : positive infinity ; FF 80 00 : -INF : negative infinity ;*/ ; ;#define FpBIAS 0x7F ; ;#ifndef FpFlags_defined ; #define FpFlags_defined ; ; char FpFlags; ; //bit IOV @ FpFlags.0; // integer overflow flag: NOT USED ; bit FpOverflow @ FpFlags.1; // floating point overflow flag ; bit FpUnderFlow @ FpFlags.2; // floating point underflow flag ; bit FpDiv0 @ FpFlags.3; // floating point divide by zero flag ; //bit FpNAN @ FpFlags.4; // not-a-number exception flag: NOT USED ; bit FpDomainError @ FpFlags.5; // domain error exception flag ; bit FpRounding @ FpFlags.6; // floating point rounding flag, 0=truncation ; // 1 = unbiased rounding to nearest LSB ; //bit FpSaturate @ FpFlags.7; // floating point saturate flag: NOT USED ; ; #pragma floatOverflow FpOverflow ; #pragma floatUnderflow FpUnderFlow ; ; #define InitFpFlags() FpFlags = 0x40 /* enable rounding as default */ ;#endif ; ;#ifdef DISABLE_ROUNDING ; #pragma floatRounding 0 ;#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 ; ; ; ;float24 operator* _fmul24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _fmul24 ; uns16 aarg; ; W = arg1f24.mid8; m001 MOV W,arg1f24+1 ; aarg.high8 = W; MOV aarg+1,W ; ; // save sign ; char sign = arg2f24.mid8 ^ W; // before first overflow test XOR W,arg2f24+1 MOV sign,W ; ; W = arg1f24.high8; MOV W,arg1f24+2 ; if ( !Zero_) SB 3.Zero_ ; W = arg2f24.high8; MOV W,arg2f24+2 ; if ( Zero_) SNB 3.Zero_ ; goto RES0; JMP m008 ; ; arg1f24.high8 += W /* arg2f24.high8 */; ADD arg1f24+2,W ; W = FpBIAS-1; MOV W,#126 ; if ( Carry) { SB 3.Carry JMP m002 ; arg1f24.high8 -= W; SUB arg1f24+2,W ; if ( Carry) SB 3.Carry JMP m003 ; goto OVERFLOW; JMP m009 ; } ; else { ; arg1f24.high8 -= W; m002 SUB arg1f24+2,W ; if ( !Carry) SB 3.Carry ; goto UNDERFLOW; JMP m007 ; } ; aarg.low8 = arg1f24.low8; m003 MOV W,arg1f24 MOV aarg,W ; ; aarg.15 = 1; SETB aarg+1.7 ; arg2f24.15 = 1; SETB arg2f24+1.7 ; ; arg1f24.low16 = 0; CLR arg1f24 CLR arg1f24+1 ; ; char counter = sizeof(aarg)*8; MOV W,#16 MOV counter,W ; ; do { ; aarg = rr( aarg); m004 RR aarg+1 RR aarg ; if ( Carry) { SB 3.Carry JMP m005 ; arg1f24.low8 += arg2f24.low8; MOV W,arg2f24 ADD arg1f24,W ; genAdd( arg1f24.mid8, arg2f24.mid8); MOV W,arg2f24+1 SNB 3.Carry MOVSZ W,++arg2f24+1 ADD arg1f24+1,W ; } ; arg1f24.low16 = rr( arg1f24.low16); m005 RR arg1f24+1 RR arg1f24 ; } while ( -- counter > 0); DECSZ counter JMP m004 ; ; if ( !arg1f24.15) { SNB arg1f24+1.7 JMP m006 ; // catch Carry bit that was shifted out previously ; arg1f24.low16 = rl( arg1f24.low16); RL arg1f24 RL arg1f24+1 ; if ( arg1f24.high8 == 0) TEST arg1f24+2 SNB 3.Zero_ ; goto UNDERFLOW; JMP m007 ; arg1f24.high8 -= 1; DEC arg1f24+2 ; W = rl( aarg.high8); MOV W,< 0); DECSZ counter_2 JMP m015 ; ; ; ;#else // SIZE ; ; goto START; ; ;// MAIN LOOP ; do { ; LOOP: ; if ( Carry) ; goto SUBTRACT; ; START: ; W = aarg.low8 - arg2f24.low8; ; genSubW( aarg.high8, arg2f24.mid8); ; if (!Carry) ; goto SKIP_SUB; ; SUBTRACT: ; aarg.low8 -= arg2f24.low8; ; genSub( aarg.high8, arg2f24.mid8); ; Carry = 1; ; SKIP_SUB: ; arg1f24.low16 = rl( arg1f24.low16); ; // Carry = 0; // ok ; aarg = rl( aarg); ; } while ( -- counter > 0); ; ;#endif ; ; if ( !arg1f24.15) { SNB arg1f24+1.7 JMP m020 ; if ( !arg1f24.high8) TEST arg1f24+2 SNB 3.Zero_ ; goto UNDERFLOW; JMP m023 ; arg1f24.high8 --; DEC arg1f24+2 ; counter ++; INC counter_2 ; goto LOOP; JMP m015 ; } ; ; #ifndef DISABLE_ROUNDING ; if ( FpRounding) { m020 SB 26.FpRounding JMP m028 ; if ( Carry) SNB 3.Carry ; goto ADD_1; JMP m021 ; aarg.low8 -= arg2f24.low8; MOV W,arg2f24 SUB aarg_2,W ; genSub( aarg.high8, arg2f24.mid8); MOV W,arg2f24+1 SB 3.Carry MOVSZ W,++arg2f24+1 SUB aarg_2+1,W ; if (Carry) { SB 3.Carry JMP m028 ; ADD_1: ; arg1f24.low8 += 1; m021 INCSZ arg1f24 ; if ( !arg1f24.low8) { JMP m028 ; arg1f24.mid8 ++; INCSZ arg1f24+1 ; if ( !arg1f24.mid8) { JMP m028 ; arg1f24.low16 = rr( arg1f24.low16); RR arg1f24+1 RR arg1f24 ; arg1f24.high8 ++; INCSZ arg1f24+2 ; if ( !arg1f24.high8) JMP m028 ; goto OVERFLOW; JMP m025 ; } ; } ; } ; } ; #endif ; goto SET_SIGN; ; ; Div0: ; FpDiv0 = 1; m022 SETB 26.FpDiv0 ; goto SATURATE; JMP m026 ; ; UNDERFLOW: ; FpUnderFlow = 1; m023 SETB 26.FpUnderFlow ; RES0: ; arg1f24.high8 = 0; m024 CLR arg1f24+2 ; goto MANTISSA; JMP m027 ; ; OVERFLOW: ; FpOverflow = 1; m025 SETB 26.FpOverflow ; SATURATE: ; arg1f24.high8 = 0xFF; m026 MOV W,#255 MOV arg1f24+2,W ; MANTISSA: ; arg1f24.low16 = 0x8000; m027 CLR arg1f24 MOV W,#128 MOV arg1f24+1,W ; ; SET_SIGN: ; if ( !(sign & 0x80)) m028 SB sign_2.7 ; arg1f24.15 = 0; CLRB arg1f24+1.7 ; return arg1f24; MOV W,arg1f24 RET ;} ; ; ;float24 operator+ _fadd24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _fadd24 ; char xtra, temp; ; char expo = arg1f24.high8 - arg2f24.high8; MOV W,arg2f24+2 MOV W,arg1f24+2-W MOV expo,W ; if ( !Carry) { SNB 3.Carry JMP m029 ; expo = -expo; NOT expo INC expo ; temp = arg1f24.high8; MOV W,arg1f24+2 MOV temp,W ; arg1f24.high8 = arg2f24.high8; MOV W,arg2f24+2 MOV arg1f24+2,W ; arg2f24.high8 = temp; MOV W,temp MOV arg2f24+2,W ; temp = arg1f24.mid8; MOV W,arg1f24+1 MOV temp,W ; arg1f24.mid8 = arg2f24.mid8; MOV W,arg2f24+1 MOV arg1f24+1,W ; arg2f24.mid8 = temp; MOV W,temp MOV arg2f24+1,W ; temp = arg1f24.low8; MOV W,arg1f24 MOV temp,W ; arg1f24.low8 = arg2f24.low8; MOV W,arg2f24 MOV arg1f24,W ; arg2f24.low8 = temp; MOV W,temp MOV arg2f24,W ; } ; if ( expo > sizeof(arg1f24)*8-7) m029 MOV W,#18 MOV W,expo-W SNB 3.Carry ; goto RETURN; JMP m047 ; if ( !arg2f24.high8) TEST arg2f24+2 SNB 3.Zero_ ; goto RETURN; // result is arg1f24 JMP m047 ; ; xtra = 0; CLR xtra ; ; temp = arg1f24.mid8; MOV W,arg1f24+1 MOV temp,W ; char sign = arg2f24.mid8 ^ arg1f24.mid8; XOR W,arg2f24+1 MOV sign_3,W ; arg1f24.15 = 1; SETB arg1f24+1.7 ; arg2f24.15 = 1; SETB arg2f24+1.7 ; ; while (1) { ; W = 8; m030 MOV W,#8 ; expo -= W; SUB expo,W ; if ( !Carry) SB 3.Carry ; break; JMP m031 ; xtra = arg2f24.low8; MOV W,arg2f24 MOV xtra,W ; arg2f24.low8 = arg2f24.mid8; MOV W,arg2f24+1 MOV arg2f24,W ; arg2f24.mid8 = 0; CLR arg2f24+1 ; } JMP m030 ; expo += W; m031 ADD expo,W ; if ( expo) { SNB 3.Zero_ JMP m033 ; do { ; Carry = 0; m032 CLRB 3.Carry ; arg2f24.low16 = rr( arg2f24.low16); RR arg2f24+1 RR arg2f24 ; xtra = rr( xtra); RR xtra ; } while (--expo > 0); DECSZ expo JMP m032 ; } ; ; ; if ( sign & 0x80) { m033 SB sign_3.7 JMP m039 ; // SUBTRACT ; arg1f24.low8 -= arg2f24.low8; MOV W,arg2f24 SUB arg1f24,W ; genSub( arg1f24.mid8, arg2f24.mid8); MOV W,arg2f24+1 SB 3.Carry MOVSZ W,++arg2f24+1 SUB arg1f24+1,W ; if (!Carry) { // arg2f24 > arg1f24 SNB 3.Carry JMP m034 ; arg1f24.low16 = -arg1f24.low16; NOT arg1f24+1 NOT arg1f24 INC arg1f24 SNB 3.Zero_ INC arg1f24+1 ; // xtra == 0 because arg1f24.exp == arg2f24.exp ; temp ^= 0x80; // invert sign MOV W,#128 XOR temp,W ; } ; xtra = -xtra; m034 NOT xtra INC xtra ; if ( xtra) SNB 3.Zero_ JMP m035 ; arg1f24.low16 --; DEC arg1f24 MOV W,++arg1f24 SNB 3.Zero_ DEC arg1f24+1 ; // adjust result left ; #define counter expo ; counter = 3; m035 MOV W,#3 MOV expo,W ; while ( !arg1f24.mid8) { m036 TEST arg1f24+1 SB 3.Zero_ JMP m037 ; arg1f24.mid8 = arg1f24.low8; MOV W,arg1f24 MOV arg1f24+1,W ; arg1f24.low8 = xtra; MOV W,xtra MOV arg1f24,W ; xtra = 0; CLR xtra ; arg1f24.high8 -= 8; MOV W,#8 SUB arg1f24+2,W ; if ( !Carry) SB 3.Carry ; goto RES0; JMP m043 ; if ( --counter == 0) // max 2 iterations DECSZ expo JMP m036 ; goto RES0; JMP m043 ; } ; #undef counter ; while ( !arg1f24.15) { m037 SNB arg1f24+1.7 JMP m038 ; Carry = 0; CLRB 3.Carry ; xtra = rl( xtra); RL xtra ; arg1f24.low16 = rl( arg1f24.low16); RL arg1f24 RL arg1f24+1 ; arg1f24.high8 --; DECSZ arg1f24+2 ; if ( !arg1f24.high8) JMP m037 ; goto RES0; // UNDERFLOW? JMP m043 ; } ; #ifndef DISABLE_ROUNDING ; if ( FpRounding && (xtra & 0x80)) { m038 SB 26.FpRounding JMP m046 SB xtra.7 JMP m046 ; xtra = 0; // disable recursion CLR xtra ; goto INCREMENT; JMP m042 ; } ; #endif ; } ; else { ; // ADD arg1f24 and arg2f24 ; arg1f24.low8 += arg2f24.low8; m039 MOV W,arg2f24 ADD arg1f24,W ; genAdd( arg1f24.mid8, arg2f24.mid8); MOV W,arg2f24+1 SNB 3.Carry MOVSZ W,++arg2f24+1 ADD arg1f24+1,W ; if ( Carry) { SB 3.Carry JMP m041 ; ADJUST_RIGHT: ; arg1f24.low16 = rr( arg1f24.low16); m040 RR arg1f24+1 RR arg1f24 ; xtra = rr( xtra); RR xtra ; arg1f24.high8 += 1; // exp INC arg1f24+2 ; if ( !arg1f24.high8) SNB 3.Zero_ ; goto OVERFLOW; JMP m044 ; } ; #ifndef DISABLE_ROUNDING ; if ( FpRounding && (xtra & 0x80)) { m041 SB 26.FpRounding JMP m046 SB xtra.7 JMP m046 ; INCREMENT: ; arg1f24.low8 += 1; m042 INCSZ arg1f24 ; if ( !arg1f24.low8) { JMP m046 ; arg1f24.mid8 += 1; INCSZ arg1f24+1 ; if ( !arg1f24.mid8) { JMP m046 ; Carry = 1; // prepare for shift SETB 3.Carry ; arg1f24.0 = 0; // disable recursion CLRB arg1f24.0 ; goto ADJUST_RIGHT; JMP m040 ; } ; } ; } ; #endif ; } ; goto SET_SIGN; ; ;// UNDERFLOW: ;// FpUnderFlow = 1; ; RES0: ; arg1f24.high8 = 0; m043 CLR arg1f24+2 ; goto MANTISSA; JMP m045 ; ; OVERFLOW: ; FpOverflow = 1; m044 SETB 26.FpOverflow ; arg1f24.high8 = 0xFF; MOV W,#255 MOV arg1f24+2,W ; MANTISSA: ; arg1f24.low16 = 0x8000; m045 CLR arg1f24 MOV W,#128 MOV arg1f24+1,W ; ; SET_SIGN: ; if ( !(temp & 0x80)) m046 SB temp.7 ; arg1f24.15 = 0; CLRB arg1f24+1.7 ; ; RETURN: ; return arg1f24; m047 MOV W,arg1f24 RET ;} ; ; ;// SUBTRACTION ; ;float24 operator- _fsub24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _fsub24 ; arg2f24.mid8 ^= 0x80; ; arg1f24 += arg2f24; ; return arg1f24; ;} ; ; ;float24 operator=( int8 arg) @ ;float24 operator=( uns8 arg) @ ;float24 operator=( int16 arg) @ ;float24 operator=( uns16 arg) @ ;float24 operator= _int24ToFloat24( sharedM int24 arg1f24) ;{ ; sharedM float24 arg2f24; // unused, but required ; char expo = FpBIAS + 16 - 1; m048 MOV W,#142 MOV expo_2,W ; char sign = 0; CLR sign_4 ; if ( arg1f24 < 0) { SB arg1f24+2.7 JMP m050 ; arg1f24 = -arg1f24; NOT arg1f24+2 NOT arg1f24+1 NOT arg1f24 INCSZ arg1f24 JMP m049 INC arg1f24+1 SNB 3.Zero_ INC arg1f24+2 ; sign |= 0x80; m049 SETB sign_4.7 ; } ; if ( arg1f24.high8) { m050 TEST arg1f24+2 SNB 3.Zero_ JMP m052 ; #ifndef DISABLE_ROUNDING ; if ( FpRounding && (arg1f24.low8 & 0x80)) { SB 26.FpRounding JMP m051 SB arg1f24.7 JMP m051 ; arg1f24.mid8 += 1; INCSZ arg1f24+1 ; if ( !arg1f24.mid8) { JMP m051 ; arg1f24.high8 += 1; INCSZ arg1f24+2 ; if ( !arg1f24.high8) { JMP m051 ; Carry = 1; SETB 3.Carry ; arg1f24.high16 = rr( arg1f24.high16); RR arg1f24+2 RR arg1f24+1 ; expo ++; INC expo_2 ; } ; } ; } ; #endif ; expo += 8; m051 MOV W,#8 ADD expo_2,W ; arg1f24.low8 = arg1f24.mid8; MOV W,arg1f24+1 MOV arg1f24,W ; arg1f24.mid8 = arg1f24.high8; MOV W,arg1f24+2 MOV arg1f24+1,W ; } ; else if ( !arg1f24.midL8) { JMP m054 m052 TEST arg1f24+1 SB 3.Zero_ JMP m054 ; expo -= 8; MOV W,#8 SUB expo_2,W ; W = arg1f24.low8; MOV W,arg1f24 ; if ( !W) SNB 3.Zero_ ; goto RETURN; JMP m055 ; arg1f24.mid8 = W; MOV arg1f24+1,W ; arg1f24.low8 = 0; CLR arg1f24 ; } ; ; // arg1f24.mid8 != 0 ; goto TEST_ARG1_B15; JMP m054 ; do { ; Carry = 0; m053 CLRB 3.Carry ; arg1f24.low16 = rl( arg1f24.low16); RL arg1f24 RL arg1f24+1 ; expo --; DEC expo_2 ; TEST_ARG1_B15: ; } while ( !arg1f24.15); m054 SB arg1f24+1.7 JMP m053 ; ; arg1f24.high8 = expo; MOV W,expo_2 MOV arg1f24+2,W ; if ( !(sign & 0x80)) SB sign_4.7 ; arg1f24.15 = 0; CLRB arg1f24+1.7 ; ; RETURN: ; float24 rval @ arg1f24; ; rval.low24 = arg1f24.low24; ; return rval; m055 MOV W,rval RET ;} ; ; ;float24 operator=( uns24 arg) @ ;float24 operator= _int32ToFloat24( int32 arg32) ;{ _int32ToFloat24 ; char expo = FpBIAS + 16 - 1; ; char sign = 0; ; if ( arg32 < 0) { ; arg32 = -arg32; ; sign |= 0x80; ; } ; if ( arg32.high8) { ; expo += 8; ; arg32.low8 = arg32.midL8; ; arg32.midL8 = arg32.midH8; ; arg32.midH8 = arg32.high8; ; } ; if ( arg32.midH8) { ; #ifndef DISABLE_ROUNDING ; if ( FpRounding && (arg32.low8 & 0x80)) { ; arg32.mid8 += 1; ; if ( !arg32.mid8) { ; arg32.high8 += 1; ; if ( !arg32.high8) { ; Carry = 1; ; arg32.high16 = rr( arg32.high16); ; expo ++; ; } ; } ; } ; #endif ; expo += 8; ; arg32.low8 = arg32.midL8; ; arg32.midL8 = arg32.midH8; ; } ; else if ( !arg32.midL8) { ; expo -= 8; ; W = arg32.low8; ; if ( !W) ; goto RETURN; ; arg32.midL8 = W; ; arg32.low8 = 0; ; } ; ; // arg32.mid8 != 0 ; goto TEST_ARG_B15; ; do { ; Carry = 0; ; arg32.low16 = rl( arg32.low16); ; expo --; ; TEST_ARG_B15: ; } while ( !arg32.15); ; ; arg32.midH8 = expo; ; if ( !(sign & 0x80)) ; arg32.15 = 0; ; ; RETURN: ; float24 rval @ arg32; ; rval.low24 = arg32.low24; ; return rval; ;} ; ; ;uns8 operator=( sharedM float24 arg1f24) @ ;int8 operator=( sharedM float24 arg1f24) @ ;uns16 operator=( sharedM float24 arg1f24) @ ;int16 operator=( sharedM float24 arg1f24) @ ;int24 operator= _float24ToInt24( sharedM float24 arg1f24) ;{ ; sharedM float24 arg2f24; // unused, but required ; char sign = arg1f24.mid8; m056 MOV W,arg1f24+1 MOV sign_6,W ; char expo = arg1f24.high8 - FpBIAS; MOV W,#127 MOV W,arg1f24+2-W MOV expo_4,W ; if ( !Carry) SB 3.Carry ; goto RES0; JMP m062 ; arg1f24.15 = 1; SETB arg1f24+1.7 ; ; arg1f24.high8 = 0; CLR arg1f24+2 ; #ifndef DISABLE_ROUNDING ; char xtra = 0; CLR xtra_2 ; #endif ; ; // (a): expo = 0..7 : shift 1 byte to the right ; // (b): expo = 8..15: shift 0 byte ; // (c): expo = 16..23: shift 1 byte to the left ; #if __CoreSet__ / 100 == 12 ; expo -= 16; MOV W,#16 SUB expo_4,W ; expo = 0xFF - expo; // COMF (Carry unchanged) NOT expo_4 ; if ( Carry) { // (c) SB 3.Carry JMP m057 ; #else ; expo = 15 - expo; ; if ( !Carry) { // (c) ; #endif ; expo += 8; MOV W,#8 ADD expo_4,W ; if (!Carry) SB 3.Carry ; goto OVERFLOW; JMP m063 ; arg1f24.high8 = arg1f24.mid8; MOV W,arg1f24+1 MOV arg1f24+2,W ; arg1f24.mid8 = arg1f24.low8; MOV W,arg1f24 MOV arg1f24+1,W ; arg1f24.low8 = 0; CLR arg1f24 ; } ; else { // (a) (b) JMP m058 ; // expo = 0 .. 15 ; W = expo - 8; m057 MOV W,#8 MOV W,expo_4-W ; if ( Carry) { // (a) SB 3.Carry JMP m058 ; expo = W; MOV expo_4,W ; #ifndef DISABLE_ROUNDING ; xtra = arg1f24.low8; MOV W,arg1f24 MOV xtra_2,W ; #endif ; arg1f24.low8 = arg1f24.mid8; MOV W,arg1f24+1 MOV arg1f24,W ; arg1f24.mid8 = 0; CLR arg1f24+1 ; } ; } ; if ( expo) { m058 TEST expo_4 SNB 3.Zero_ JMP m060 ; do { ; Carry = 0; m059 CLRB 3.Carry ; arg1f24.high8 = rr( arg1f24.high8); RR arg1f24+2 ; arg1f24.low16 = rr( arg1f24.low16); RR arg1f24+1 RR arg1f24 ; #ifndef DISABLE_ROUNDING ; xtra = rr( xtra); RR xtra_2 ; #endif ; } while ( --expo); DECSZ expo_4 JMP m059 ; } ; if (arg1f24.23) m060 SNB arg1f24+2.7 ; goto OVERFLOW; JMP m063 ; #ifndef DISABLE_ROUNDING ; if ( FpRounding && (xtra & 0x80)) { SB 26.FpRounding JMP m061 SB xtra_2.7 JMP m061 ; arg1f24.low8 += 1; INCSZ arg1f24 ; if (!arg1f24.low8) { JMP m061 ; arg1f24.mid8 += 1; INCSZ arg1f24+1 ; if (!arg1f24.mid8) { JMP m061 ; arg1f24.high8 += 1; INC arg1f24+2 ; if (arg1f24.23) SNB arg1f24+2.7 ; goto OVERFLOW; JMP m063 ; } ; } ; } ; #endif ; if ( sign & 0x80) m061 SB sign_6.7 JMP m065 ; arg1f24.low24 = -arg1f24.low24; NOT arg1f24+2 NOT arg1f24+1 NOT arg1f24 INCSZ arg1f24 JMP m065 INC arg1f24+1 SNB 3.Zero_ INC arg1f24+2 ; goto RETURN; JMP m065 ; ; RES0: ; W = 0; m062 CLR W ; goto ASSIGNW; JMP m064 ; OVERFLOW: ; FpOverflow = 1; m063 SETB 26.FpOverflow ; W = 0xFF; MOV W,#255 ; ASSIGNW: ; arg1f24.high8 = W; m064 MOV arg1f24+2,W ; arg1f24.mid8 = W; MOV arg1f24+1,W ; arg1f24.low8 = W; MOV arg1f24,W ; arg1f24.23 = 0; CLRB arg1f24+2.7 ; ; RETURN: ; int24 rval @ arg1f24; ; rval = arg1f24.low24; ; return rval; m065 MOV W,rval_3 RETP ;} ; ; ;bit operator< _f24_LT_f24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _f24_LT_f24 ; Carry = 0; ; if ( !(arg1f24.high8 | arg2f24.high8)) ; return Carry; ; if ( !arg1f24.15) { ; if ( arg2f24.15) ; return Carry; ; W = arg1f24.low8 - arg2f24.low8; ; genSubW( arg1f24.mid8, arg2f24.mid8); ; genSubW( arg1f24.high8, arg2f24.high8); ; goto RETURN; ; } ; if ( !arg2f24.15) ; goto RETURN; ; W = arg2f24.low8 - arg1f24.low8; ; genSubW( arg2f24.mid8, arg1f24.mid8); ; genSubW( arg2f24.high8, arg1f24.high8); ; RETURN: ; if (Carry) ; return 0; ; return 1; ;} ; ; ;bit operator>= _f24_GE_f24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _f24_GE_f24 ; Carry = 1; ; if ( !(arg1f24.high8 | arg2f24.high8)) ; return Carry; ; if ( !arg1f24.15) { ; if ( arg2f24.15) ; return Carry; ; W = arg1f24.low8 - arg2f24.low8; ; genSubW( arg1f24.mid8, arg2f24.mid8); ; genSubW( arg1f24.high8, arg2f24.high8); ; return Carry; ; } ; Carry = 0; ; if ( !arg2f24.15) ; return Carry; ; W = arg2f24.low8 - arg1f24.low8; ; genSubW( arg2f24.mid8, arg1f24.mid8); ; genSubW( arg2f24.high8, arg1f24.high8); ; return Carry; ;} ; ; ; ;bit operator> _f24_GT_f24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _f24_GT_f24 ; Carry = 0; ; if ( !(arg1f24.high8 | arg2f24.high8)) ; return Carry; ; if ( !arg1f24.15) { ; if ( arg2f24.15) ; goto RETURN; ; W = arg2f24.low8 - arg1f24.low8; ; genSubW( arg2f24.mid8, arg1f24.mid8); ; genSubW( arg2f24.high8, arg1f24.high8); ; goto RETURN; ; } ; if ( !arg2f24.15) ; return Carry; ; W = arg1f24.low8 - arg2f24.low8; ; genSubW( arg1f24.mid8, arg2f24.mid8); ; genSubW( arg1f24.high8, arg2f24.high8); ; RETURN: ; if (Carry) ; return 0; ; return 1; ;} ; ; ; ;bit operator<= _f24_LE_f24( sharedM float24 arg1f24, sharedM float24 arg2f24) ;{ _f24_LE_f24 ; Carry = 1; ; if ( !(arg1f24.high8 | arg2f24.high8)) ; return Carry; ; if ( !arg1f24.15) { ; Carry = 0; ; if ( arg2f24.15) ; return Carry; ; W = arg2f24.low8 - arg1f24.low8; ; genSubW( arg2f24.mid8, arg1f24.mid8); ; genSubW( arg2f24.high8, arg1f24.high8); ; return Carry; ; } ; if ( !arg2f24.15) ; return Carry; ; W = arg1f24.low8 - arg2f24.low8; ; genSubW( arg1f24.mid8, arg2f24.mid8); ; genSubW( arg1f24.high8, arg2f24.high8); ; return Carry; ; FILE sx\demo-fpm.c ;#include "math24f.h" ;#pragma codepage 0 ORG $0000 ; ;uns16 ad_data; ;bank1 float tx, av, mg, a, vx; ;bank2 float prev, kp; ; ;void main(void) ;{ main ; InitFpFlags(); // enable rounding as default MOV W,#64 CLR FSR MOV FpFlags,W ; vx = 3.127; MOV W,#33 BANK 32 MOV vx,W MOV W,#72 MOV vx+1,W MOV W,#128 MOV vx+2,W ; tx += ad_data; // automatic type cast BANK 0 MOV W,ad_data MOV arg1f24,W MOV W,ad_data+1 MOV arg1f24+1,W CLR arg1f24+2 PAGE 512 CALL _int24ToFloat24 BANK 32 MOV W,tx BANK 0 MOV arg2f24,W BANK 32 MOV W,tx+1 BANK 0 MOV arg2f24+1,W BANK 32 MOV W,tx+2 BANK 0 MOV arg2f24+2,W CALL _fadd24 BANK 32 MOV tx,W BANK 0 MOV W,arg1f24+1 BANK 32 MOV tx+1,W BANK 0 MOV W,arg1f24+2 BANK 32 MOV tx+2,W ; ad_data = kp; // assign integer part BANK 64 MOV W,kp BANK 0 MOV arg1f24,W BANK 64 MOV W,kp+1 BANK 0 MOV arg1f24+1,W BANK 64 MOV W,kp+2 BANK 0 MOV arg1f24+2,W CALL _float24ToInt24 MOV ad_data,W MOV W,rval_3+1 MOV ad_data+1,W ; if ( tx < 0) BANK 32 MOV W,tx+2 SNB 3.Zero_ JMP m066 SB tx+1.7 JMP m066 ; tx = -tx; // make positive MOV W,#128 XOR tx+1,W ; av = tx/20.0; m066 MOV W,tx BANK 0 MOV arg1f24,W BANK 32 MOV W,tx+1 BANK 0 MOV arg1f24+1,W BANK 32 MOV W,tx+2 BANK 0 MOV arg1f24+2,W CLR arg2f24 MOV W,#32 MOV arg2f24+1,W MOV W,#131 MOV arg2f24+2,W PAGE 512 CALL _fdiv24 BANK 32 MOV av,W BANK 0 MOV W,arg1f24+1 BANK 32 MOV av+1,W BANK 0 MOV W,arg1f24+2 BANK 32 MOV av+2,W ; mg = av * 1.25; MOV W,av BANK 0 MOV arg1f24,W BANK 32 MOV W,av+1 BANK 0 MOV arg1f24+1,W BANK 32 MOV W,av+2 BANK 0 MOV arg1f24+2,W CLR arg2f24 MOV W,#32 MOV arg2f24+1,W MOV W,#127 MOV arg2f24+2,W CALL _fmul24 BANK 32 MOV mg,W BANK 0 MOV W,arg1f24+1 BANK 32 MOV mg+1,W BANK 0 MOV W,arg1f24+2 BANK 32 MOV mg+2,W ; a = mg * 0.98; MOV W,mg BANK 0 MOV arg1f24,W BANK 32 MOV W,mg+1 BANK 0 MOV arg1f24+1,W BANK 32 MOV W,mg+2 BANK 0 MOV arg1f24+2,W MOV W,#225 MOV arg2f24,W MOV W,#122 MOV arg2f24+1,W MOV W,#126 MOV arg2f24+2,W CALL _fmul24 BANK 32 MOV a,W BANK 0 MOV W,arg1f24+1 BANK 32 MOV a+1,W BANK 0 MOV W,arg1f24+2 BANK 32 MOV a+2,W ; prev = vx; MOV W,vx BANK 64 MOV prev,W BANK 32 MOV W,vx+1 BANK 64 MOV prev+1,W BANK 32 MOV W,vx+2 BANK 64 MOV prev+2,W ; vx = a/5.0 + prev; BANK 32 MOV W,a BANK 0 MOV arg1f24,W BANK 32 MOV W,a+1 BANK 0 MOV arg1f24+1,W BANK 32 MOV W,a+2 BANK 0 MOV arg1f24+2,W CLR arg2f24 MOV W,#32 MOV arg2f24+1,W MOV W,#129 MOV arg2f24+2,W CALL _fdiv24 BANK 64 MOV W,prev BANK 0 MOV arg2f24,W BANK 64 MOV W,prev+1 BANK 0 MOV arg2f24+1,W BANK 64 MOV W,prev+2 BANK 0 MOV arg2f24+2,W CALL _fadd24 BANK 32 MOV vx,W BANK 0 MOV W,arg1f24+1 BANK 32 MOV vx+1,W BANK 0 MOV W,arg1f24+2 BANK 32 MOV vx+2,W ; ; kp = vx * 0.036; MOV W,vx BANK 0 MOV arg1f24,W BANK 32 MOV W,vx+1 BANK 0 MOV arg1f24+1,W BANK 32 MOV W,vx+2 BANK 0 MOV arg1f24+2,W MOV W,#117 MOV arg2f24,W MOV W,#19 MOV arg2f24+1,W MOV W,#122 MOV arg2f24+2,W CALL _fmul24 BANK 64 MOV kp,W BANK 0 MOV W,arg1f24+1 BANK 64 MOV kp+1,W BANK 0 MOV W,arg1f24+2 BANK 64 MOV kp+2,W ; kp = vx / (1.0/0.036); BANK 32 MOV W,vx BANK 0 MOV arg1f24,W BANK 32 MOV W,vx+1 BANK 0 MOV arg1f24+1,W BANK 32 MOV W,vx+2 BANK 0 MOV arg1f24+2,W MOV W,#57 MOV arg2f24,W MOV W,#94 MOV arg2f24+1,W MOV W,#131 MOV arg2f24+2,W CALL _fdiv24 PAGE 0 BANK 64 MOV kp,W BANK 0 MOV W,arg1f24+1 BANK 64 MOV kp+1,W BANK 0 MOV W,arg1f24+2 BANK 64 MOV kp+2,W ;} SLEEP ORG $07FF GOTO main END