;************************************************************ ;IEEE 64 Bit Floating Point Library (c) 2003 M.Cibulski ; ;Conversion Routines ; ;************************************************************ ;***************************************************************************************** ;Convert String to Float ; ;Parameters: ;X pointer to string ; ;Results - ;AKKUA floating point akkumulator A ; ;Globals - ; ;Stack ??? bytes ; ;2002-02-14 not finished ;***************************************************************************************** .DSEG flt_atof_testbuf: .byte 40 .CSEG flt_atof_x_test: ldi xl ,low(flt_atof_testbuf) ldi xh ,high(flt_atof_testbuf) ldi r16 ,'-' st X+ ,r16 ldi r16 ,'1' st X+ ,r16 ldi r16 ,' ' st X+ ,r16 ldi xl ,low(flt_atof_testbuf) ldi xh ,high(flt_atof_testbuf) flt_atof_x: .EQU flt_atf_factor = 1 .EQU flt_atf_result = 9 .EQU flt_atf_sign = 17 .EQU flt_atf_cp = 18 .EQU flt_atf_c = 20 .EQU flt_atf_digit = 21 .EQU flt_atf_esign = 22 .EQU flt_atf_exp = 23 .EQU flt_atf_lspace = 25 LOCAL flt_atf_lspace nop nop flt_atof_read_spaces: ld r16 ,X+ cpi r16 ,' ' breq flt_atof_read_spaces std Y+flt_atf_sign ,r16 ;save sign cpi r16 ,'+' breq flt_atof_00 cpi r16 ,'-' breq flt_atof_00 sbiw xh:xl ,1 flt_atof_00: std Y+flt_atf_cp ,xh std Y+flt_atf_cp+1 ,xl f_const flt__1 f_store_l flt_atf_factor f_const flt__0 flt_atof_loop_pre: ldd xh ,Y+flt_atf_cp ;get next character ldd xl ,Y+flt_atf_cp+1 ld r16 ,X+ std Y+flt_atf_cp ,xh std Y+flt_atf_cp+1 ,xl std Y+flt_atf_c ,r16 tst r16 ;null byte > finished brne flt_atof_01 rjmp flt_atof_exp_end flt_atof_01: cpi r16 ,'.' ;decimal point breq flt_atof_point cpi r16 ,',' ;or comma breq flt_atof_point cpi r16 ,'E' breq flt_atof_011 cpi r16 ,'e' brne flt_atof_02 flt_atof_011: rjmp flt_atof_read_exp flt_atof_02: subi r16 ,'0' brcc flt_atof_digit_pre cpi r16 ,10 brcs flt_atof_digit_pre clt ;return false f_const flt__0 ;0.0 rjmp flt_atof_exp_end flt_atof_digit_pre: std Y+flt_atf_digit ,r16 f_push f_const flt__10 f_mul f_push ldd AKKU_3 ,Y+flt_atf_digit clr AKKU_2 call flt_convert_word f_add rjmp flt_atof_loop_pre flt_atof_point: f_store_l flt_atf_result flt_atof_loop_post: ldd xh ,Y+flt_atf_cp ;get character ldd xl ,Y+flt_atf_cp+1 ld r16 ,X+ std Y+flt_atf_cp ,xh std Y+flt_atf_cp+1 ,xl std Y+flt_atf_c ,r16 tst r16 ;null byte > finished brne flt_atof_03 rjmp flt_atof_exp_end flt_atof_03: cpi r16 ,'E' ;exponent breq flt_atof_read_exp cpi r16 ,'e' breq flt_atof_read_exp subi r16 ,'0' brcc flt_atof_digit_post cpi r16 ,10 brcs flt_atof_digit_post f_const flt__0 ;0.0 clt ;return false ??? rjmp flt_atof_exp_end flt_atof_digit_post: std Y+flt_atf_digit ,r16 f_push f_load_l flt_atf_factor f_push f_const flt__0_1 f_mul f_store_l flt_atf_factor f_push ldd AKKU_3 ,Y+flt_atf_digit clr AKKU_2 call flt_convert_word f_mul f_add rjmp flt_atof_loop_post flt_atof_read_exp: clr r17 ldd xh ,Y+flt_atf_cp ;get sign of exponent ldd xl ,Y+flt_atf_cp+1 ld r16 ,X+ std Y+flt_atf_esign ,r16 cpi r16 ,'-' breq flt_atof_04 cpi r16 ,'+' breq flt_atof_04 sbiw xh:xl ,1 flt_atof_04: clr r17 ;digit high byte clr r18 ;exp low clr r19 ;exp high ldi r22 ,4 ;read maximum 4 digits flt_atof_05: ld r16 ,X+ ;get exp digit cpi r16 ,'0' breq flt_atof_05 rjmp flt_atof_052 flt_atof_051: ld r16 ,X+ ;get exp digit flt_atof_052: subi r16 ,'0' brcs flt_atof_exp_read cpi r16 ,10 brcc flt_atof_exp_read mov r20 ,r18 ;save exp mov r21 ,r19 lsl r18 ;*2 rol r19 lsl r18 ;*4 rol r19 add r18 ,r20 ;*5 adc r19 ,r21 lsl r18 ;*10 rol r19 add r18 ,r16 ;+digit adc r19 ,r17 dec r22 ;not more than 4 digits brne flt_atof_051 flt_atof_exp_read: ldi r16 ,high(300) cpi r18 ,low(300) cpc r19 ,r16 brcs flt_atof_06 f_const flt__0 rjmp flt_atof_exp_end flt_atof_06: std Y+flt_atf_exp ,r19 std Y+flt_atf_exp+1 ,r18 ldd r16 ,Y+flt_atf_esign cpi r16 ,'-' brne flt_atof_exp_positive flt_atof_exp_negative: ldd r25 ,Y+flt_atf_exp ldd r24 ,Y+flt_atf_exp+1 sbiw r25:r24 ,1 brmi flt_atof_exp_end std Y+flt_atf_exp ,r25 std Y+flt_atf_exp+1 ,r24 f_push f_const flt__0_1 f_mul rjmp flt_atof_exp_negative flt_atof_exp_positive: ldd r25 ,Y+flt_atf_exp ldd r24 ,Y+flt_atf_exp+1 sbiw r25:r24 ,1 brmi flt_atof_exp_end std Y+flt_atf_exp ,r25 std Y+flt_atf_exp+1 ,r24 f_push f_const flt__10 f_mul rjmp flt_atof_exp_positive flt_atof_exp_end: ldd r16 ,Y+flt_atf_sign cpi r16 ,'-' brne flt_atof_end f_chs r16 flt_atof_end: set ENDLOCAL flt_atf_lspace ret ;************************************************************ ;Print Akku ; ;Parameters: ;AKKUA floating point akkumulator A ; ;Results - ; ;Globals - ; ;Stack 15+2=17 bytes ; ;2002-02-14 small numbers without exponent ;************************************************************ .CSEG .EQU flt_prt_decimals = 11 ;digits behind the decimal point flt_print__roundup: .db 0x3D,0x95,0xFD,0x7F,0xE1,0x79,0x64,0x95 ;5e-12 flt_print: .EQU flt_prt_save = 1 .EQU flt_prt_arg = 9 .EQU flt_prt_index = 17 .EQU flt_prt_digit = 18 .EQU flt_prt_exp = 26 .EQU flt_prt_lspace = 28 LOCAL flt_prt_lspace push zl push zh f_store_l flt_prt_save ;rcall _putc_init f_isnumber r16 ,flt_prt_01 ldi r16 ,'N' call putc_func ldi r16 ,'A' call putc_func ldi r16 ,'N' call putc_func rjmp flt_prt_end flt_prt_01: tst AKKU_E1 brne flt_prt_02 tst AKKU_E2 brne flt_prt_02 ldi r16 ,'0' call putc_func ldi r16 ,'.' call putc_func ldi r16 ,'0' call putc_func rjmp flt_prt_end flt_prt_02: ldi r16 ,' ' ;print no sign (space) sbrc AKKU_S ,7 ldi r16 ,'-' ;print minus sign call putc_func clr AKKU_S ;make positive flt_prt_positive: f_store_l flt_prt_arg clr r16 ;exp = 0 std Y+flt_prt_exp ,r16 flt_prt_scaledown: f_load_l flt_prt_arg ;while arg > 10.0 f_push f_const flt__10 f_sub tst AKKU_S brmi flt_prt_scaleup f_load_l flt_prt_arg ; arg = arg * 0.1 f_push f_const flt__0_1 f_mul f_store_l flt_prt_arg ldd r16 ,Y+flt_prt_exp ; exp ++ inc r16 std Y+flt_prt_exp ,r16 rjmp flt_prt_scaledown flt_prt_scaleup: f_load_l flt_prt_arg ;while arg < 1.0 f_push f_const flt__1 f_sub tst AKKU_S brpl flt_prt_scaled_to_1_10 f_load_l flt_prt_arg ; arg = arg * 10.0 f_push f_const flt__10 f_mul f_store_l flt_prt_arg ldd r16 ,Y+flt_prt_exp ; exp -- dec r16 std Y+flt_prt_exp ,r16 rjmp flt_prt_scaleup flt_prt_scaled_to_1_10: f_load_l flt_prt_arg ;add 0.5 in last digit position f_push f_const flt_print__roundup f_add f_store_l flt_prt_arg f_push ;check if arg became >10.0 now f_const flt__10 f_sub tst AKKU_S brmi flt_prt_first_digit ;no additional scaling needed f_load_l flt_prt_arg ; scale down once more f_push f_const flt__0_1 f_mul f_store_l flt_prt_arg ldd r16 ,Y+flt_prt_exp ; exp ++ inc r16 std Y+flt_prt_exp ,r16 flt_prt_first_digit: f_load_l flt_prt_arg call flt_floor f_store_l flt_prt_digit call flt_double2word ldi r16 ,'0' add r16 ,AKKU_3 call putc_func ldi r16 ,'.' call putc_func ldi r16 ,flt_prt_decimals std Y+flt_prt_index ,r16 flt_prt_loop1: f_load_l flt_prt_arg f_push f_load_l flt_prt_digit f_sub f_push f_const flt__10 f_mul f_store_l flt_prt_arg f_floor f_store_l flt_prt_digit call flt_double2word ldi r16 ,'0' add r16 ,AKKU_3 call putc_func ldd r16 ,Y+flt_prt_index dec r16 std Y+flt_prt_index ,r16 breq flt_prt_mant_done rjmp flt_prt_loop1 flt_prt_mant_done: ldi r16 ,'e' call putc_func ldi r16 ,'+' ldd r17 ,Y+flt_prt_exp tst r17 brpl flt_prt_exp_positive ldi r16 ,'-' neg r17 std Y+flt_prt_exp ,r17 flt_prt_exp_positive: call putc_func ldd r17 ,Y+flt_prt_exp ldi r16 ,'0' flt_prt_exp_100: cpi r17 ,100 brcs flt_prt_exp_no100 subi r17 ,100 std Y+flt_prt_exp ,r17 inc r16 rjmp flt_prt_exp_100 flt_prt_exp_no100: call putc_func flt_prt_10: ldd r17 ,Y+flt_prt_exp ldi r16 ,'0' flt_prt_exp_10: cpi r17 ,10 brcs flt_prt_exp_no10 subi r17 ,10 std Y+flt_prt_exp ,r17 inc r16 rjmp flt_prt_exp_10 flt_prt_exp_no10: call putc_func flt_prt_1: ldd r17 ,Y+flt_prt_exp ldi r16 ,'0' flt_prt_exp_1: cpi r17 ,1 brcs flt_prt_exp_no1 subi r17 ,1 inc r16 rjmp flt_prt_exp_1 flt_prt_exp_no1: call putc_func flt_prt_end: f_load_l flt_prt_save pop zh pop zl ENDLOCAL flt_prt_lspace ret ;************************************************************