;************************************************************ ;IEEE 64 Bit Floating Point Library (c) 2003 M.Cibulski ; ;Transcend Functions ; ;************************************************************ ;************************************************************ ;Cosine ; ;Parameters: ;Akku A X ; ;Registers: ;AKKU floating point akkumulator ;AKKUB temporary for RAM variable ; ;************************************************************ .CSEG flt_cos: f_push push zl push zh f_const flt__pi2 pop zh pop zl f_add rjmp flt_sin ;************************************************************ ;Sinus of Akku A ; ;Parameters: ;Akku A X ; ;Registers: ;AKKU floating point akkumulator ;AKKUB temporary for RAM variable ; ;************************************************************ .CSEG flt_sin_sincof: .DB 0x3d,0xe5,0xd8,0xfd,0x1f,0xd1,0x9c,0xcd ; 1.58962301576546568060E-10, .DB 0xbe,0x5a,0xe5,0xe5,0xa9,0x29,0x1f,0x5d ;-2.50507477628578072866E-8, .DB 0x3e,0xc7,0x1d,0xe3,0x56,0x7d,0x48,0xa1 ; 2.75573136213857245213E-6, .DB 0xbf,0x2a,0x01,0xa0,0x19,0xbf,0xdf,0x03 ;-1.98412698295895385996E-4, .DB 0x3f,0x81,0x11,0x11,0x11,0x10,0xf7,0xd0 ; 8.33333333332211858878E-3, .DB 0xbf,0xc5,0x55,0x55,0x55,0x55,0x55,0x48 ;-1.66666666666666307295E-1, .DB 0xFF,0xFF flt_sin_coscof: .DB 0xbd,0xa8,0xfa,0x49,0xa0,0x86,0x1a,0x9b ;-1.13585365213876817300E-11, .DB 0x3e,0x21,0xee,0x9d,0x7b,0x4e,0x3f,0x05 ; 2.08757008419747316778E-9, .DB 0xbe,0x92,0x7e,0x4f,0x7e,0xac,0x4b,0xc6 ;-2.75573141792967388112E-7, .DB 0x3e,0xfa,0x01,0xa0,0x19,0xc8,0x44,0xf5 ; 2.48015872888517045348E-5, .DB 0xbf,0x56,0xc1,0x6c,0x16,0xc1,0x4f,0x91 ;-1.38888888888730564116E-3, .DB 0x3f,0xa5,0x55,0x55,0x55,0x55,0x55,0x4b ; 4.16666666666665929218E-2, .DB 0xFF,0xFF flt_sin_p1: .DB 0x3f,0xe9,0x21,0xfb,0x40,0x00,0x00,0x00 ; 7.85398125648498535156E-1; flt_sin_p2: .DB 0x3e,0x64,0x44,0x2d,0x00,0x00,0x00,0x00 ; 3.77489470793079817668E-8 flt_sin_p3: .DB 0x3c,0xe8,0x46,0x98,0x98,0xcc,0x51,0x70 ; 2.69515142907905952645E-15; flt_sin_max_x: .DB 0x41,0xCD,0xCD,0x65,0x00,0x00,0x00,0x00 ; 1E+9 flt_sin: .EQU flt_sin_x = 1 .EQU flt_sin_y = 9 .EQU flt_sin_z = 17 .EQU flt_sin_zz = 25 .EQU flt_sin_save = 33 .EQU flt_sin_sign = 41 .EQU flt_sin_j = 42 .EQU flt_sin_lspace = 43 LOCAL flt_sin_lspace push zl push zh ;call flt_check_nan_a ;x=NAN ? ;brtc flt_sin_01 ;rjmp flt_sin_end ; return NAN flt_sin_01: ;call flt_check_zero_a ;x=0 ? ;brtc flt_sin_02 ;rjmp flt_sin_end ; return 0 flt_sin_02: std Y+flt_sin_sign ,AKKU_S ;save sign clr AKKU_S ;make x positive f_push f_const flt_sin_max_x ;x > 1E9 f_y_gt_x f_pop brtc flt_sin_03 ;no f_zero ;x too big, return 0.0 rjmp flt_sin_end flt_sin_03: f_store_l flt_sin_x f_push ;y = floor( x/PIO4 ); /* integer part of x/PIO4 */ f_const flt__pi4 f_div f_floor f_store_l flt_sin_y tst AKKU_E1 brne flt_sin_10 tst AKKU_E2 breq flt_sin_09 flt_sin_10: ;strip high bits of integer part to prevent integer overflow ldi r16 ,4 ;y/16 sub AKKU_E2 ,r16 clr r16 sbc AKKU_E1 ,r16 f_floor ;integer part of y/16 ldi r16 ,4 ;*16 add AKKU_E2 ,r16 clr r16 adc AKKU_E1 ,r16 f_push f_load_l flt_sin_y f_sub f_chs r16 ;y - 16 * integer_part(y/16) flt_sin_09: f_store_l flt_sin_z ldi r16 ,3 ;j = z (integer, for tests on the phase angle) sub AKKU_E2 ,r16 flt_sin_04: asr AKKU_2 inc AKKU_E2 brne flt_sin_04 std Y+flt_sin_j ,AKKU_2 ldi r16 ,0x01 ;if( j & 1 ) and AKKU_2 ,r16 breq flt_sin_05 ldd r16 ,Y+flt_sin_j ; j += 1; inc r16 std Y+flt_sin_j ,r16 f_load_l flt_sin_y ; y += 1.0; f_push f_const flt__1 f_add f_store_l flt_sin_y flt_sin_05: ldd r16 ,Y+flt_sin_j ;j = j & 07; /* octant modulo 360 degrees */ andi r16 ,0x07 cpi r16 ,4 ;if( j > 3) brcs flt_sin_06 subi r16 ,4 ; j -= 4; ldd r17 ,Y+flt_sin_sign ; sign = -sign; subi r17 ,0x80 std Y+flt_sin_sign ,r17 flt_sin_06: std Y+flt_sin_j ,r16 ;/* Extended precision modular arithmetic */ ;z = ((x - y * DP1) - y * DP2) - y * DP3; f_load_l flt_sin_y f_push f_const flt_sin_p1 f_mul f_chs r16 f_push f_load_l flt_sin_x f_add f_push f_load_l flt_sin_y f_push f_const flt_sin_p2 f_mul f_sub f_push f_load_l flt_sin_y f_push f_const flt_sin_p3 f_mul f_sub f_store_l flt_sin_z f_push f_mul f_store_l flt_sin_zz ldd r16 ,Y+flt_sin_j ;if( (j==1) || (j==2) ) cpi r16 ,1 breq flt_sin_07 cpi r16 ,2 brne flt_sin_08 flt_sin_07: f_powerseries flt_sin_coscof ;y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); f_push f_load_l flt_sin_zz f_push f_mul f_mul f_push f_const flt__1 f_push f_load_l flt_sin_zz ;f_subexp r16 ,1 ldi r16 ,low(1) ;exponent -1 sub AKKU_E2 ,r16 ldi r16 ,high(1) sbc AKKU_E1 ,r16 f_sub f_add f_store_l flt_sin_y rjmp flt_sin_99 flt_sin_08: ;else f_powerseries flt_sin_sincof ;y = z + z * (zz * polevl( zz, sincof, 5 )); f_push f_load_l flt_sin_zz f_mul f_push f_load_l flt_sin_z f_mul f_push f_load_l flt_sin_z f_add flt_sin_99: ldd r16 ,Y+flt_sin_sign ;if(sign < 0) add AKKU_S ,r16 ; y = -y; flt_sin_end: pop zh pop zl endlocal flt_sin_lspace ret ;************************************************************