scs83
Junior Member level 1
Hi,
I am having some difficulties with some coding again. Please help me. The todec suborutine is to cenvert the answer to decimal while the enter subroutine is called twice, each time after I entered the first and second operands. The results that I wanted is not that accurate so I am thinking it is these two subroutines that is the problem. Hope that there is someone who is willing to read through the code for me. Thanks. By the way this project is a calculator project.
I am having some difficulties with some coding again. Please help me. The todec suborutine is to cenvert the answer to decimal while the enter subroutine is called twice, each time after I entered the first and second operands. The results that I wanted is not that accurate so I am thinking it is these two subroutines that is the problem. Hope that there is someone who is willing to read through the code for me. Thanks. By the way this project is a calculator project.
Code:
;*****************************************************
;subroutine to convert answer to decimal
;*****************************************************
todec: ldi ZL, low(answer) ;Z points to answer
ldi ZH, high(answer)
sign: cpi op2hi,0x80 ;compare op2hi to 0x80
brlo load1 ;if lower than goto load1
ldi temp, '-' ;else op2 is negative
st Z+,temp ;store '-' in answer and inc Z
com op2hi ;negate op2
com op2lo
ldi temp,1
add op2lo,temp
ldi temp,0
adc op2hi,temp
load1: ldi temp, azero ;load temp with ascii 0
hunds: cpi op2hi, 100 ;compare op2hi to 100
brlo load2 ;if less then 100 goto load2
inc temp ;if greater then or equal to 100 inc temp
subi op2hi, 100 ;subtract 100 from op2hi
rjmp hunds ;goto hunds
load2: st Z+, temp ;load hundreds digit into answer, inc Z
ldi temp, azero ;reload temp with ascii 0
tens: cpi op2hi, 10 ;compare op2hi to 10
brlo load3 ;if less then 10 goto load3
inc temp ;if greater then or equal to 10 increment temp
subi op2hi, 10 ;subtract 10 from op2hi
rjmp tens ;goto tens
load3: st Z+, temp ;load tens digit into answer, inc Z
ldi temp, azero ;reload temp with ascii 0
ones: add temp, op2hi ;now temp = temp + op2hi
st Z+, temp ;load ones digit into answer, inc Z
cpi op2lo,0x00 ;compare op2lo to 0
breq fino ;if equal, goto fino
ldi temp, '.' ;else, store '.' in answer and inc Z
st Z+, temp
ldi temp, azero ;reload temp with ascii 0
tenths: cpi op2lo, 0b00011001 ;compare op2lo with .1
brlo load4 ;if less than goto load4
inc temp ;if greater than or equal inc temp
subi op2lo, 0b00011001 ;subtract .1 from op2lo
rjmp tenths ;goto tenths
load4: st Z+,temp ;store tenths digit in answer and inc Z
ldi temp, azero ;reload temp with ascii 0
hundths: cpi op2lo, 0b00000011 ;compare op2lo with .01
brlo pfino ;if less than goto pfino
inc temp ;inc temp
subi op2lo, 0b00000011 ;subtract .01 from op2lo
rjmp hundths ;goto hundths
pfino: st Z+,temp ;store hundreths digit in answer and inc Z
fino: clr temp ;clear temp
st Z+,temp ;store temp in answer and inc Z
ret ;return
;*****************************************************
;subroutine to handle enter key
;*****************************************************
;table to determine power of 10 to multiply current digit by
EXP10: cpi temp, 2 ;is temp 2?
brne e1 ;if not goto e1
ldi temp, 100 ;temp = 100
ret ;return
e1: cpi temp, 1 ;is temp 1?
brne e2 ;if not goto e2
ldi temp, 10 ;temp = 10
ret ;return
e2: cpi temp, 0 ;is temp 0?
brne e3 ;if not goto e3
ldi temp, 1 ;temp = 1
ret ;return
e3: cpi temp, 0xff ;is temp 0xff (-1)
brne e4 ;if not goto e4
ldi temp, 0b00011001 ;temp = .1
ret ;return
e4: cpi temp, 0xfe ;is temp 0xfe (-2)
brne e5 ;if not goto e5
ldi temp, 0b00000011 ;temp = .01
e5: ret ;return
ENTER: clr negflag ;clear negflag
ldi temp, 1 ;set charin to 1
mov charin, temp
ldi ZH, high(buffer) ;buffer address to Z-ptr
ldi ZL, low(buffer)
find: ld butnum, Z+ ;load character Z points to into butnum and inc Z
cpi butnum, '.' ;is butnum the decimal point?
breq form ;if so goto form
inc charin ;else inc charin
cp nchar, charin ;compare charin to number of characters
brsh find ;if nchar is the same or higher than charin goto find
form: ldi ZH, high(buffer) ;buffer address to Z-ptr
ldi ZL, low(buffer)
mov ptind, charin ;move charin to ptind
clr numblo ;clear numb
clr numbhi
ldi temp, 1 ;reset charin to 1
mov charin, temp
ld butnum, Z ;load character Z points to into butnum
cpi butnum, '-' ;is butnum the negative sign?
brne f2 ;if not, goto f2
ldi temp,0xFF ;else set the negflag
mov negflag,temp
adiw ZL,1 ;inc Z
inc charin ;inc charin
f2: cp charin, ptind ;compare charin to ptind
breq f11 ;if equal goto f11
mov temp, ptind ;temp = (ptind - charin - 1)
sub temp, charin
subi temp, 1
rcall exp10 ;call exp10
ld op1hi, Z+ ;load character Z points to into op1hi
clr op1lo ;clear op1lo
mov op2hi, temp ;move temp into op2hi
clr op2lo ;clear op2lo
rcall fix_mult ;call fix_mult
add numbhi, op2hi ;add op2hi to numbhi
inc charin ;inc charin
rjmp f2 ;goto f2
f11: adiw Zl, 1 ;inc Z
f1: inc charin ;inc charin
cp nchar, charin ;compare nchar to charin
brsh fno ;if nchar is the same or higher than charin goto fno
mov temp,negflag ;move negflag to temp
cpi temp,0xFF ;compare to 0xFF
brne f3 ;if not equal goto f3
com numbhi ;negate numb
com numblo
ldi temp,1
add numblo,temp
ldi temp,0
adc numbhi,temp
f3: ret ;return
fno: mov temp, ptind ;move ptind to temp
sub temp, charin ;temp = (ptind-charind)
rcall exp10 ;call exp10
mov op2lo, temp ;move temp to op2lo
clr op2hi ;clear op2hi
ld op1hi, Z+ ;load character Z points to into op1hi
clr op1lo ;clear op1lo
rcall fix_mult ;call fix_mult
add numblo, op2lo ;add op2lo to numblo
rjmp f1 ;goto f1