; 32bit Floating point package for the 8051 ; Created by Jerson Fernandes for the C16 meta assembler ; floating point format ; exponent, 24 bits mantissa ; xxxxxxxx, Sxxxxxxx xxxxxxxx xxxxxxxx ; stored internally from right to left CPU "8051.tbl" hof "INT8" incl "8051sfr.asm" ORG 8 ;internal memory float_arg: equ 3 ;3 bytes mantissa float_exp: equ 1 ;1 byte exponent expbias: equ 128 ;exponent bias Quo: dfs float_arg ;holds quotient of divide Aarg: dfs float_arg Aexp: dfs float_exp Barg: dfs float_arg Bexp: dfs float_exp Aext: dfs 1 ;extension for Aarg Aext2: dfs 1 ;for holding the aligned bit TOS: ORG 0 ;This segment is to test the functionality of the library start: mov sp,#TOS ;point to the top of stack mov Aarg,#low 1 mov Aarg+1,#high 1 mov Aarg+2,#0 ;high -10 acall int2float ; acall copy_ab ; mov Aarg,#low 1000 mov Aarg+1,#high 1000 mov Aarg+2,#0 acall int2float ; acall fpmul32 mov a,aarg push acc mov a,Aarg+1 push acc mov a,Aarg+2 push acc mov a,Aexp push acc mov Aarg,#low 2000 mov Aarg+1,#high 2000 mov Aarg+2,#0 acall int2float acall copy_ab pop acc mov Aexp,a pop acc mov Aarg+2,a pop acc mov Aarg+1,a pop acc mov Aarg,a lcall fpdiv32 acall float2int sjmp start ; This is where the library begins ;Copy ArgA to ArgB Copy_AB:mov r7,#float_arg mov r0,#Aarg mov r1,#Barg copy_AB_5: mov a,@r0 mov @r1,a inc r0 inc r1 djnz r7,copy_AB_5 mov Bexp,Aexp ret ; Convert a integer to a floating point number ; Input - 24 bit signed integer @ Aarg ; Output- 32 bit floating point number @ Aarg int2float: acall Normalize ret ; Normalize the 24 bit signed integer in Aarg Normalize: mov r6,#24 ;exponent counter mov a,Aarg+2 ;extract sign anl a,#80h mov r5,a ;keep in R5 jz norm5 ;negative number make +ve as we have the sign mov a,Aarg cpl a add a,#1 ;2s complement mov Aarg,a mov a,Aarg+1 cpl a addc a,#0 mov Aarg+1,a mov a,Aarg+2 cpl a addc a,#0 mov Aarg+2,a Norm5: mov r0,#Aarg+2 mov a,@r0 orl a,#0 jnz Norm10 ;the highest 8 are 0, shift 8 mov a,#0 xch a,Aarg xch a,Aarg+1 xch a,Aarg+2 clr c mov a,r6 subb a,#8 mov r6,a ;update the exponent ; jnc Norm5 Norm10:mov a,@r0 ;read the msb jb ACC+7,Norm_end ;shift one bit left mov a,Aarg clr c rlc a mov Aarg,a mov a,Aarg+1 rlc a mov Aarg+1,a mov a,Aarg+2 rlc a mov Aarg+2,a djnz r6,Norm10 ;note the shift in the exponent too Norm_end: mov a,#expbias add a,r6 mov Aexp,a ;now make the msbit implicit and put in the sign there mov a,r5 orl a,#7fh anl a,Aarg+2 mov Aarg+2,a ;sign is always for int2float ret ; Float to integer conversion routine ; Input - floating point number in Aarg,Aexp ; Output- 24 bit signed integer in Aarg float2int: mov a,Aexp clr c subb a,#expbias jc res032 ;result is 0 cjne a,#24,$+3 ;overflow,return a 0 int jnc res032 mov r6,a ;keep the exponent here ;find out how much to shift the float to get our int mov a,#24 clr c subb a,r6 mov r6,a ;take out the sign and make msb explicit mov a,Aarg+2 ;keep in R5 mov r5,a orl a,#80h mov Aarg+2,a ;explicit msb ;now shift the float to form the int flint10: mov a,r6 ;if exp >= 8, shift bytes clr c subb a,#9 jnc flint20 ;now do bit shifts flint15: clr c mov a,Aarg+2 rrc a mov Aarg+2,a mov a,Aarg+1 rrc a mov Aarg+1,a mov a,Aarg+0 rrc a mov Aarg+0,a djnz r6,flint15 ;we're done getting the int,restore the sign mov a,r5 anl a,#80h jz flint30 ;restore the negative number mov a,Aarg cpl a add a,#1 mov Aarg,a mov a,Aarg+1 cpl a addc a,#0 mov Aarg+1,a mov a,Aarg+2 cpl a addc a,#0 mov Aarg+2,a flint30:ret flint20: ;shift right 8 bits clr a xch a,Aarg+2 xch a,Aarg+1 xch a,Aarg+0 ;and adjust the exp counter in r6 mov a,r6 subb a,#8 mov r6,a sjmp flint10 res032: clr a mov Aarg+0,a mov Aarg+1,a mov Aarg+2,a ret ;Floating point divide ; Input - Arg 1 in Aarg, Aexp ; - Arg 2 in Barg, Bexp ; Output- Divide arg1 by arg2 ; - result in Aarg ; Temp - R5 resulting sign ; acc for dividend is ; Aarg[2,1,0],Quo[2,1,0] msb first fpdiv32: ;check if Bexp == 0 mov a,Bexp jnz fpd10 ajmp fpdivz fpd10: mov a,Aarg+2 ;extract resulting sign xrl a,Barg+2 anl a,#80h ;keep the sign bit here mov r5,a ;make the msb explicit in args mov a,#80h orl a,Aarg+2 mov Aarg+2,a mov a,#80h orl a,Barg+2 mov Barg+2,a ;if A