<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>
Date   : Thu, 02 Jun 2005 19:36:05 +1000 (EST)
From   : Peter Craven <cjl_craves@...>
Subject: Re: Assembly Language Square Root 

--0-1644151922-1117704965=:55952

Hi All
I have recently been searching for the fastest method to calculate the
square root of a 16-bit number.
 
I came across a Z80 Assembly Language program at the end of the web page at: 
http://map.tni.nl/articles/mult_div_shifts.php
 
I have copied the relevant part:

(Snip)
Square root routine
This is a faster square root routine than the one previously given, test
results say that it’s 26% faster. It is written by Ricardo Bittencourt,
so many thanks to him :).
;
;Square root of 16-bit value
;In:  HL = value
;Out:  D = result (rounded down)
;
Sqr16: ld de,#0040
 ld a,l
 ld l,h
 ld h,d
 or a
 ld b,8
Sqr16_Loop:
 sbc hl,de
 jr nc,Sqr16_Skip
 add hl,de
Sqr16_Skip:
 ccf
 rl d
 add a,a
 adc hl,hl
 add a,a
 adc hl,hl
 djnz Sqr16_Loop
 ret
 
Well, that’s it. Thanks go to mr. Rodnay Zaks (although I somehow really 
doubt he’ll read this) for writing his book “Programming of the Z80”, 
which taught me about how to do multiplications on Z80, and has been the 
inspiration for the routines listed here. If you have any suggestions for
speed improvements, or know of another method which might be faster under
certain conditions, please let me know.
~Grauw
(End Snip)
 
I have tried to 'translate' this into an assembly language program that
can be used by the Master computer:
 
10 l=&70:h=&71:d=&72;e=&73:a=&74
 
20 FORp=0TO1:P%=&B00:[OPTp*2
 
30 .sqr_root STZe:LDA#40:STAd:LDAl:STAa:LDAh:STAl:LDAe:
STAh:LDX#8:LDAa:ORAa
 
40.loop LDAl:SBCd:STAl:LDAh:SBCe:STAh:BCSskip:CLC:LDAl:
ADCd:STAl:LDAh:ADCe:STAh
 
50.skip BCSskip1:SEC:BRAskip2
 
60.skip1 CLC
 
70.skip2 ROLe:ROLa:ASLl:ROLh:ROLa:ASLl:ROLh:DEX:BNEloop:
RTS
 
80 ]:NEXT
 
90 INPUT"Enter number: "N%:!l=N%AND&FFFF
 
100 CALL&B00
 
110 PRINT ?e
 
However, this produces incorrect results, namely, if enter 100, results
are ?l=220, ?h=170, ?d=40, ?e=128, 
?a=17. If enter 1000, results are ?l=40, ?h=213, 
?d=40, ?e=0,?a=0.
 
I have only recently briefly looked up how Z80 assembly language goes.
Realise 'de' has 'd' as MSB and 'e' as LSB in the Z80, so when I swaped
this in the Master program, I hoped I have kept this consistent.
 
I have used the X register in the Master program because there is no 'b'
register that uses 'djnz'.
 
I realise that the first line could have simply put STZh instead of transferring
'e' memory location to it, but I tried to keep in line with the Z80 program.
 
Thought branching is quicker in regards to complementing the carry flag,
rather than playing around with the stack and the status, etc.
 
Thought it quicker to use ASL/ ROL instead of adding in line 70.
 
I really cannot work out what I have translated wrong, but assume my lack
of Z80 skills is the cause.
 
Can anybody help out??
 
Does anyone know of a quicker routine (not including Table)??
 
Further, would anyone be interested in having a monthlty 'competition' 
where any topic is decided upon (eg. most interesting graphics design,
weirdest sounds, anything!!) and then a month is given for programs to
be submitted, and voted upon at end of month???
 
Programs could be in basic/ assembly language. Assume majority would rather
they work on Electron & BBC & Master...
 
Any takers??
 
Cheers
 
Pete



Dr Peter Craven (MBBS Uni. of Qld)

12 Treacher St

Mt Gravatt

QLD 4122

Ph (H): (07) 3349 0820







Send instant messages to your online friends http://au.messenger.yahoo.com 
--0-1644151922-1117704965=:55952

<DIV>Hi All</DIV>
<DIV>I have recently been searching for the fastest method to calculate
the square root of a 16-bit number.</DIV>
<DIV>&nbsp;</DIV>
<DIV>I came across a Z80 Assembly Language program at the end of the web
page at: </DIV>
<DIV><A href="http://map.tni.nl/articles/mult_div_shifts.php">http://map.tni.nl/articles/mult_div_shifts.php</A></DIV>
<DIV> </DIV>
<DIV>I have copied the relevant part:</DIV>
<DIV><BR><FONT color=#ff0000>(Snip)<BR></FONT><FONT color=#0000ff>Square
root routine</FONT></DIV>
<DIV><FONT color=#0000ff>This is a faster square root routine than the
one previously given, test results say that it’s 26% faster. It is written
by Ricardo Bittencourt, so many thanks to him :).</FONT></DIV>
<DIV><STRONG><FONT color=#00007f>;<BR>;Square root of 16-bit value<BR>;In:&nbsp; 
HL = value<BR>;Out:&nbsp; D = result (rounded down)<BR>;<BR>Sqr16:&nbsp;ld 
de,#0040<BR>&nbsp;ld a,l<BR>&nbsp;ld l,h<BR>&nbsp;ld h,d<BR>&nbsp;or a<BR>&nbsp;ld 
b,8<BR>Sqr16_Loop:<BR>&nbsp;sbc hl,de<BR>&nbsp;jr nc,Sqr16_Skip<BR>&nbsp;add 
hl,de<BR>Sqr16_Skip:<BR>&nbsp;ccf<BR>&nbsp;rl d<BR>&nbsp;add a,a<BR>&nbsp;adc
hl,hl<BR>&nbsp;add a,a<BR>&nbsp;adc hl,hl<BR>&nbsp;djnz Sqr16_Loop<BR>&nbsp;ret</FONT></STRONG></DIV>
<DIV><STRONG><FONT color=#00007f></FONT></STRONG>&nbsp;</DIV>
<DIV><FONT color=#0000ff>Well, that’s it. Thanks go to mr. Rodnay Zaks 
(although I somehow really doubt he’ll read this) for writing his book 
“Programming of the Z80”, which taught me about how to do multiplications 
on Z80, and has been the inspiration for the routines listed here. If you
have any suggestions for speed improvements, or know of another method
which might be faster under certain conditions, please let me know.</FONT></DIV>
<DIV><FONT color=#0000ff>~Grauw</FONT></DIV>
<DIV><FONT color=#ff0000>(End Snip)</FONT></DIV>
<DIV><FONT color=#ff0000></FONT>&nbsp;</DIV>
<DIV>I have tried to 'translate' this into an assembly language program
that can be used by the Master computer:</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT face=courier color=#00bf60>10 l=&amp;70:h=&amp;71:d=&amp;72;e=&amp;73:a=&amp;74</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>20 FORp=0TO1:P%=&amp;B00:[OPTp*2</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>30 .sqr_root STZe:LDA#40:STAd:LDAl:STAa:LDAh:STAl:LDAe:</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60>STAh:LDX#8:LDAa:ORAa</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>40.loop LDAl:SBCd:STAl:LDAh:SBCe:STAh:BCSskip:CLC:LDAl:</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60>ADCd:STAl:LDAh:ADCe:STAh</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>50.skip&nbsp;BCSskip1:SEC:BRAskip2</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>60.skip1 CLC</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>70.skip2 ROLe:ROLa:ASLl:ROLh:ROLa:ASLl:ROLh:DEX:BNEloop:</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60>RTS</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>80 ]:NEXT</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>90 INPUT"Enter number: "N%:!l=N%AND&amp;FFFF</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>100 CALL&amp;B00</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#00bf60>110 PRINT ?e</FONT></DIV>
<DIV><FONT face=Courier color=#00bf60></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier>However, this produces incorrect results, namely,
if enter 100, results are ?l=220, ?h=170, ?d=40, ?e=128, </FONT></DIV>
<DIV><FONT face=Courier>?a=17. If enter 1000, results are ?l=40, ?h=213,
</FONT></DIV>
<DIV><FONT face=Courier>?d=40, ?e=0,<FONT face=Courier>?a=0.<IMG src="http://us.i1.yimg.com/us.yimg.com/i/mesg/tsmileys2/31.gif"></FONT></FONT></DIV>
<DIV><FONT face=Courier></FONT> </DIV>
<DIV><FONT face=Courier>I have only recently briefly looked up how Z80
assembly language goes. Realise 'de' has 'd' as MSB and 'e' as LSB in the
Z80, so when I swaped this in the Master program, I hoped I have kept this
consistent.</FONT></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier>I have used the X register in the Master program
because there is no 'b' register that uses 'djnz'.</FONT></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier>I realise that the first line could have simply
put STZh instead of transferring 'e' memory location to it, but I tried
to keep in line with the Z80 program.</FONT></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier>Thought branching is quicker in regards to complementing
the carry flag, rather than playing around with the stack and the status,
etc.</FONT></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier>Thought it quicker to use ASL/ ROL instead of adding
in line 70.</FONT></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier>I really cannot work out what I have translated
wrong, but assume my lack of Z80 skills is the cause.</FONT></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier color=#ff0000 size=5><STRONG>Can anybody help out??</STRONG></FONT></DIV>
<DIV><STRONG><FONT face=Courier color=#ff0000 size=5></FONT></STRONG>&nbsp;</DIV>
<DIV><STRONG><FONT face=Courier color=#ff0000 size=5>Does anyone know of
a quicker routine (not including Table)??</FONT></STRONG></DIV>
<DIV><FONT face=Courier></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6><FONT style="BACKGROUND-COLOR: 
#ffff00">Further</FONT>, would anyone be interested in having a monthlty 
'competition' where any topic is decided upon (eg. most interesting graphics
design, weirdest sounds, anything!!)&nbsp;and then a month is given for
programs to be submitted, and voted upon at end of month???</FONT></FONT></DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6></FONT></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6>Programs could be in
basic/ assembly language. Assume majority would rather they work on Electron
&amp; BBC &amp; Master...</FONT></FONT></DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6></FONT></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6>Any takers??</FONT></FONT></DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6></FONT></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6>Cheers</FONT></FONT></DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6></FONT></FONT>&nbsp;</DIV>
<DIV><FONT face=Courier><FONT color=#00bf60 size=6>Pete</FONT></DIV></FONT><BR><BR><DIV>
<DIV>
<DIV>
<DIV>
<DIV>
<DIV>
<P>Dr Peter Craven (MBBS Uni. of Qld)</P>
<P>12 Treacher St</P>
<P>Mt Gravatt</P>
<P>QLD 4122</P>
<P>Ph (H): (07) 3349 0820</P></DIV></DIV></DIV></DIV></DIV></DIV><p>Send
instant messages to your online friends http://au.messenger.yahoo.com 
--0-1644151922-1117704965=:55952--



<< Previous Message Main Index Next Message >>
<< Previous Message in Thread This Month Next Message in Thread >>