divide by 10 with Z80  CP/M
This is a discussion on divide by 10 with Z80  CP/M ; On Jan 24, 2:24*pm, glen herrmannsfeldt wrote:
> dkel...@hotmail.com wrote:
> > *My mistake. I thought I'd stated that I was interested in small size.
> > I've posted to two other groups so I wasn't sure what I'd said ...

Re: divide by 10 with Z80
On Jan 24, 2:24*pm, glen herrmannsfeldt wrote:
> dkel...@hotmail.com wrote:
> > *My mistake. I thought I'd stated that I was interested in small size.
> > I've posted to two other groups so I wasn't sure what I'd said but
> > thought I'd stated that size was a primary criteria.
> > *I agree that posting these is a good idea.
>
> Did you try a subtract 10 each time loop?
>
> It will loop up to 79 times, but should be small. *It should
> still be faster than one step of the floppy drive head.
>
> Otherwise, there might be a routine already in the ROM that
> you could use to reduce the size.
>
>  glen
A fellow did this on another group and it produced
the smallest code. Only 11 bytes. It was really slow
for larger numbers ( over 2000 clocks ) still useful
if I need the additional 5 bytes.
My main purpose is to, one time, read the disk images and I
intend to transfer the data over a serial line. Such a
calcultion is not out of line for that purpose. Since
I want to do the disk serially, I might just make a
simple increment routine and not divide at all.
Dwight

Re: divide by 10 with Z80
On Jan 24, 2:24*pm, glen herrmannsfeldt wrote:
> dkel...@hotmail.com wrote:
> > *My mistake. I thought I'd stated that I was interested in small size.
> > I've posted to two other groups so I wasn't sure what I'd said but
> > thought I'd stated that size was a primary criteria.
> > *I agree that posting these is a good idea.
>
> Did you try a subtract 10 each time loop?
>
> It will loop up to 79 times, but should be small. *It should
> still be faster than one step of the floppy drive head.
>
> Otherwise, there might be a routine already in the ROM that
> you could use to reduce the size.
>
>  glen
Hi Glen
Forgot to mention, the ROM is setup for 32 hard sectored
8 inch disk. I want to do the least modifications to use it
for 5.25 10 sectored. I'll use much of the code for
the 8 inch with a few minor tweaks for a small change in
format, sector size and sector count. I've already modified
the board with a crystal change and a few capacitors to
get it to run at the 5.25 data rate. The PLL is descrete
parts and was easy to modify.
It is from a Polymorphic system using System88 OS.
I have a working system using single density disk but
I have archive disk that are double that I wish to get the
data from. I had a card for the 8 inch 32 sectored double
density disk.
Dwight

Re: divide by 10 with Z80
On Jan 24, 2:02*pm, "dkel...@hotmail.com" wrote:
> On Jan 24, 1:50 pm, "dkel...@hotmail.com" wrote:
>
>
>
>
>
> > On Jan 23, 12:43 pm, glen herrmannsfeldt
> > wrote:
>
> > > dkel...@hotmail.com wrote:
> > > > On Jan 22, 2:36 pm, glen herrmannsfeldt wrote:
>
> > > (snip)
>
> > > >>More obvious to me, multiply by 205 and shift right 11 bits.
> > > >>205 is X'CD', or binary 11001101. *There should be some
> > > >>optimal combinations of shift, add, and store that can
> > > >>do that.
> > > > *That gives me the quotient but not the remainder. I need both.
> > > > The quotient is the track while the remainder is the sector.
> > > > Both are required.
> > > > *Also, the calculation exceeds 16 bits and doesn't fit into
> > > > a register pair ( 800 x 205 = 164000 ).
>
> > > Yes, I tried ones that would fit, but at some point it
> > > rounds the wrong way.
>
> > > > If it didn't over flow, it might look like:
>
> > > (snip of 16 bit product code)
>
> > > > *But, as I said, this is only half the problem. I still need the
> > > > remainder that would require me to multiply by 10 and then subtract.
>
> > > It still might be faster, but maybe not smaller.
>
> > > A loop subtracting 10 each time while counting up might be
> > > smaller, though slower.
>
> > >  glen
>
> > Hi Glen
> > *For speed, one might use a smaller number and expect the result
> > to be off some. One could treat this as a trial quotient.
> > *Calculate the remainder using the multiply by 10 and then check
> > the size of the remainder. If the error was over small enough range,
> > one could do maybe 2 or 3 compares of the remainder to determine
> > how far off it was.
> > *Of course, one could first do a trial of all of the values to
> > see how big the maximum error was over the range of numbers. This
> > would
> > simplify the testing.
> > *This has the advantage that one only needs maybe 2 or 3
> > conditionals and the rest is all inline, as I described. No need for
> > time consuming loops.
> > *I'll think about this over the weekend and post what I come up with.
> > I think the error will always be that the remainder is too large so
> > testing should be simple.
> > Dwight
>
> Hi Glen
> *I just did a quick check. It looks like a multiply by 51d, instead
> of 205. It will work if I shift the answer in HL right by 1.
> *I just checked it for the 800 case and it is only off by 10. That is
> only
> one compare. I'll have to run some test cases to try all the values
> from 0 to 799. If worst case is only off by 1 in the quotient, this
> would be a really fast way to do this calculation.
> Dwight Hide quoted text 
>
>  Show quoted text 
Hi Glen
I worked on the idea of multiplying and here is my result.
It is about 30 bytes and runs in only 230 clocks. It also
has no conditional code!
; divides 0799 by 10
; hl is input dividend
; a= qoutient
; l=remainder
Div10fast:
ld d,h
ld e,l
add hl,hl
add hl,hl
add hl,de
add hl,hl
ld b,h
ld c,l
add hl,hl
add hl,hl
add hl,bc
add hl,de ; dividend *51
ld a,h ; add little more accuracy
add a,#16d ; tweak value
ld c,ald b,#0
add hl,bc ; add corrections for truncation
ld a,h ; quo*2
rra ; quo=a but still need remainder
ld l,a
ld c,a
ld h,b
add hl,hl
add hl,hl
add hl,bc
add hl,hl ; quo*10 to calc Remainder
ex de,hl
sbc hl,de ; l= remainder
ret