I'm trying to figure out how to speed up this code for my 8051 processor.
I'm currently using it to divide numbers by 10 so I can pick up digits to directly
print on an LCD. The part that takes the longest is this code. The reason why I'm using
24-bit dividend is because I want to display more than 5 digits for a number, and with
24-bits, I can go up to 8 digits.
Is there a way I can modify all this code so it can execute faster?
I tried removing subtraction lines with stars and that made things worse.
I'm currently using it to divide numbers by 10 so I can pick up digits to directly
print on an LCD. The part that takes the longest is this code. The reason why I'm using
24-bit dividend is because I want to display more than 5 digits for a number, and with
24-bits, I can go up to 8 digits.
Is there a way I can modify all this code so it can execute faster?
I tried removing subtraction lines with stars and that made things worse.
Code:
;DIVIDH/DIVIDM/DIVIDL = 24-bit dividend temporary storage
;DIVISH/DIVISM/DIVISL = 24-bit divisor temporary storage
;DIVTH/DIVTM/DIVTL = 24-bit temporary number
;QUOTH/QUOTM/QOTL = 24-bit quotient
;NUMSPC = number space in memory (uses up to 8 bytes)
;number is 12345678 in decimal
mov R7,#0BCh
mov DPTR,#0614Eh
lcall digits
;returns R0 indicating # of digits and
;NUMSPC to NUMSPC+R0 memory locations filled with the correct digits
sjmp $
digits:
;breaks R7:DPH:DPL (24-bit) to single digits
;storage starting at NUMSPC. Digits are reversed
mov R0,#NUMSPC
moredig:
;divide by 10
mov DIVISH,#0h
mov DIVISM,#0h
mov DIVISL,#0Ah
lcall ldiv
;store remainder and increment memory address
mov @R0,A
inc R0
mov A,DPL
orl A,DPH
orl A,R7
jnz noz1
;R0 = number of digits
mov A,R0
subb A,#NUMSPC
mov R0,A
ret
noz1:
;keep going until quotient = 0
sjmp moredig
;24-bit division
ldiv:
;R7:DPH:DPL = 24-bit dividend in, 24-bit quotient out, R6:A=remainder
;get input + clear quotient, counter and carry
mov DIVIDL,DPL
mov DIVIDM,DPH
mov DIVIDH,R7
mov QUOTL,#0h
mov QUOTM,#0h
mov QUOTH,#0h
clr C/mov R6,#0h
div1:
;Shift 24-bit divisor left until MSB shifted is a 1
mov A,DIVISL
rlc A
mov DIVISL,A
mov A,DIVISM
rlc A
mov DIVISM,A
mov A,DIVISH
rlc A
mov DIVISH,A
inc R6
jnc div1
div2:
;Shift 24-bit divisor right only once
mov A,DIVISH
rrc A
mov DIVISH,A
mov A,DIVISM
rrc A
mov DIVISM,A
mov A,DIVISL
rrc A
mov DIVISL,A
;store dividend as a temporary number
mov DIVTL,DIVIDL/mov DIVTH,DIVIDH/mov DIVTM,DIVIDM
;subtract divisor from dividend
mov A,DIVIDL
subb A,DIVISL
mov DIVIDL,A
mov A,DIVIDM
subb A,DIVISM ;**
mov DIVIDM,A
mov A,DIVIDH
subb A,DIVISH ;**
mov DIVIDH,A
jnc norevdivid
;restore original dividend if result of subtraction is negative number
mov DIVIDL,DIVTL
mov DIVIDM,DIVTM
mov DIVIDH,DIVTH
norevdivid:
;complement carry so correct bit value gets shifted in result
cpl C
;shift bit into result
mov A,QUOTL
rlc A
mov QUOTL,A
mov A,QUOTM
rlc A
mov QUOTM,A
mov A,QUOTH
rlc A
mov QUOTH,A
;keep going until divisor is shifted back
djnz R6,div2
;R7:DPH:DPL=quotient
mov DPL,QUOTL
mov DPH,QUOTM
mov R7,QUOTH
R6:A=remainder
mov R6,DIVIDM
mov A,DIVIDL
ret