div by 10 on Z80 was RE: Reading Polymorphic ---
dwight elvey
dkelvey at hotmail.com
Sun Jan 20 11:02:20 CST 2008
> From: dkelvey at hotmail.com
>
>
>> From: cclist at sydex.com
>>
>> Date: Fri, 18 Jan 2008 18:20:45 -0800
>> From: dwight elvey
>>
>>> For this, I need a little help. Since the 8 inch drives were 32 sectored,
>>> calculating tracks from a disk offset number was easy. 5.25 disk with 10
>>> sectored will require something different. Is there an easy way to to
>>> separate track from sector using Z80 code? Dwight
>>
>> Do you mean "is there an easy way to divide by 10?". If so, yes:
>>
>> 0.100x = x/16+x/32+x/256+x/4096+x/8192
>>
>> to about 0.04 percent (4 parts in 10,000). Truncate the series if
>> you need less accuracy. Ask if you need Z80 code.
>>
>> Cheers,
>> Chuck
>>
>
> Hi Chuck
> I'm not sure how effective that would be in Z80 code. It looks
> like I'd at least need to do 32 bit coding to keep track of things.
> I'd still need to calculate the remainder when done( I need both ).
> The maximum sector index would be 800 decimal. I came up
> with the following code to do this all in Z80 code but I'm interested
> both compact and fast, with more emphasis on compact.
> Here is the code I've made so far:
>
> ; hl is value to be divided by 10
> ; max hl will be 800
> ; uses a, bc, de and hl
> ; returns a = quotient
> ; h = remainder
> ; uses 42 bytes
>
> div10:
> xor a
> ld bc -640d
> ld de 640d
> call div10s
> call div10s
> call div10s
> call div10s
> call div10s
> call div10s
> call div10s
> add hl,hl
> ret
>
> div10s:
> add a,a
> add hl,bc
> jp c,div10s1
> add hl,de
> jp div10s2
> div10s1:
> inc a
> div10s2:
> add hl,hl
> ret
>
> After the first two calls, I could do the rest as byte operations
> but I think the total byte cost would be greater.
> I'm looking for other ideas on smaller code. It would be nice
> to hace one more 8 bit register as a counter.
> Dwight
>
Hi
Pete Turnbull sent some suggestions and here is what we have
now. It trades a little speed for size but the inner loop is faster
As I stated, faster is good but smaller is better. Any more help
would be great:
Next try at code:
div10:
xor a
ld de,#-640d ; largest power of 2 times 10 less then 800d
ld b,#7 ; only seven loops needed to finish divide 800/10
divloop:
call div10s ; divide steps
djnz divloop
add hl,hl ; push full remainder in HL
ret
div10s:
add a,a ; 2*a
add hl,de ; trial subtract
jr c,div10s1 ; carry means trial passed
sbc hl,de ; undo previous add, carry is clear
dec a ; to nullify the following inc
div10s1:
inc a ; add to quotient
add hl,hl ; shift number to reuse same constant, 640 decimal
ret
This is 23 bytes and looks good.
Dwight
_________________________________________________________________
Connect and share in new ways with Windows Live.
http://www.windowslive.com/share.html?ocid=TXT_TAGHM_Wave2_sharelife_012008
More information about the cctech
mailing list