![]() |
||||||
| Microcontroller Kits Simple
Mikrokontroller 89s51 Trainer All Item Include
|
32bit Floating point package for the 8051
; 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<B mantissa, divide, else align
clr a
mov Quo,a
mov Quo+1,a
mov Quo+2,a
clr c
mov a,Aarg
subb a,Barg
mov a,Aarg+1
subb a,Barg+1
mov a,Aarg+2
subb a,Barg+2
jc fpdok
;make A mantissa < B mantissa
clr c
mov a,Aarg+2 ;msb
rrc a
mov Aarg+2,a
mov a,Aarg+1
rrc a
mov Aarg+1,a
mov a,Aarg
rrc a
mov Aarg,a ;lsb
mov a,Aext2 ;msb
rrc a
mov Aext2,a ;move into quotient
;adjust the Aexp accordingly
mov a,Aexp
inc a
mov Aexp,a
;get the resulting exponent in Aexp
fpdok: clr c
mov a,Aexp
subb a,Bexp
add a,#expbias
mov Aexp,a ;resulting exponent here
fpdargok:
clr a
mov Aext,a
mov r7,#24 ;initialize bit counter for divide
fpdloop32:
;shift left 1 bit
clr c
mov a,Aext2
rlc a
mov Aext2,a
mov a,Aarg+0
rlc a
mov Aarg+0,a
mov a,Aarg+1
rlc a
mov Aarg+1,a
mov a,Aarg+2
rlc a
mov Aarg+2,a
;move the bit into our accumulator
mov a,Aext
rlc a
mov Aext,a
;subtract
clr c
mov a,Aarg+0
subb a,Barg+0
mov a,Aarg+1
subb a,Barg+1
mov a,Aarg+2
subb a,Barg+2
mov a,Aext
subb a,#0
jc nosub ;cannot subtract
clr c
mov a,Aarg+0 ;subtract
subb a,Barg+0
mov Aarg+0,a
mov a,Aarg+1
subb a,Barg+1
mov Aarg+1,a
mov a,Aarg+2
subb a,Barg+2
mov Aarg+2,a
mov a,Aext
subb a,#0
mov Aext,a
nosub: cpl c ;shift in the complement of C
mov a,Quo ;into the result
rlc a
mov Quo,a
mov a,Quo+1
rlc a
mov Quo+1,a
mov a,Quo+2
rlc a
mov Quo+2,a
djnz r7,fpdloop32
;move the quotient to Aarg and make msb implicit
mov a,Quo+1
mov Aarg+1,a
mov a,Quo+0
mov Aarg+0,a
mov a,r5
jnz minusdiv
mov a,Quo+2
anl a,#7fh ;make msb implicit if +ve number
mov Aarg+2,a
ret
minusdiv:
mov a,Quo+2
mov Aarg+2,a
ret
fpdivz:
;return divide by zero error
ret
fpov: ;return divide overflow
ret
;Floating point multiplication
; Input - Aarg,Aexp
; - Barg,Bexp
; Output- Aarg,Aexp
; partial product = Quo[2..0],Aarg[2..0]
fpmul32:
;if A == 0 || B == 0 result = 0
mov a,Aexp
jz fpm10
mov a,Bexp
jnz fpm20
fpm10: ljmp res032
fpm20: ; get the resulting exponent
clr c
mov a,Aexp
subb a,#expbias
add a,Bexp
mov Aexp,a ;store resulting exponent here
jnc fpm30
ljmp fpov
fpm30: ;make the msbs explicit
mov a,Aarg+2
orl a,#80h
mov Aarg+2,a
mov a,Barg+2
orl a,#80h
mov Barg+2,a
;now multiply using Quo as the partial product
clr a
mov Quo,a
mov Quo+1,a
mov Quo+2,a
mov r7,#24 ;bits
fpmloop:
;
mov a,Aarg
rrc a
jnc fpmnoadd
;add the multiplier to the product
mov a,Quo
add a,Barg
mov Quo,a
mov a,Quo+1
addc a,Barg+1
mov Quo+1,a
mov a,Quo+2
addc a,Barg+2
mov Quo+2,a
fpmnoadd:
;right shift the product
mov a,Quo+2
rrc a
mov Quo+2,a
mov a,Quo+1
rrc a
mov Quo+1,a
mov a,Quo
rrc a
mov Quo,a
;shift right the multiplicand
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
rrc a
mov Aarg,a
fpm40: djnz r7,fpmloop
;multiplication is over
;check for normalisation now
mov a,Quo+2
jb acc+7,fpm50
clr c
mov a,Quo
rlc a
mov Quo,a
mov a,Quo+1
rlc a
mov Quo+1,a
mov a,Quo+2
rlc a
mov Quo+2,a
dec Aexp
fpm50: mov Aarg,Quo
mov Aarg+1,Quo+1
mov a,r5
anl a,#80h ;check sign of result
jz fpmplus
mov Aarg+2,Quo+2
ret
fpmplus:
mov a,Quo+2
anl a,#7fh
mov Aarg+2,a
ret
Comments, questions and discussion about this topic
|
|
||||