/*****************************************************************************/
/*									     */
/*  128/64 BIT DIVIDE (UNSIGNED)					     */
/*  01/12/07 (dkc)							     */
/*									     */
/*****************************************************************************/
unsigned int carry(unsigned int a, unsigned int b, unsigned int sum);
unsigned int lmbd(unsigned int mode, unsigned int a);
void div128_64(unsigned int a0, unsigned int a1, unsigned int a2,
	       unsigned int a3, unsigned int *quotient, unsigned int d2,
	       unsigned int d3) {
unsigned int i,d0,d1,dshift,ashift,count,flag;
unsigned int shift,c,c0,c1,c2,temp,temp0,temp1,temp2,temp3;

if (d2==0) {
   if ((a0==0)&&(a1==0)&&(a2==0)&&(a3<d3)) {
      *quotient=0;
      *(quotient+1)=0;
      *(quotient+2)=0;
      *(quotient+3)=0;
      return;
      }
   }
else {
   if ((a0==0)&&(a1==0)&&(a2<d2)) {
      *quotient=0;
      *(quotient+1)=0;
      *(quotient+2)=0;
      *(quotient+3)=0;
      return;
      }
   }
dshift=lmbd(1,d2);
if (d2==0)
   dshift+=lmbd(1,d3);
dshift+=64;

ashift=lmbd(1,a0);
if (a0==0)
   ashift+=lmbd(1,a1);
if ((a0|a1)==0)
   ashift+=lmbd(1,a2);
if ((a0|a1|a2)==0)
   ashift+=lmbd(1,a3);

shift=dshift-ashift;
count=shift+1;
d0=0;
d1=0;
if (shift<32) {
   if (shift!=0) {
      d1=d2>>(32-shift);
      d2=(d2<<shift)|(d3>>(32-shift));
      }
   else
      d1=0;		       // added to get MSVC to work
   d3=d3<<shift;
   flag=3;
   shift=32-shift;
   }
else {
   shift=shift-32;
   d1=d2;
   d2=d3;
   d3=0;
   if (shift<32) {
      if (shift!=0) {
	 d0=d1>>(32-shift);
	 d1=(d1<<shift)|(d2>>(32-shift));
	 }
      else
	 d0=0;		       // added to get MSVC to work
      d2=d2<<shift;
      flag=2;
      shift=32-shift;
      }
   else {
      shift=shift-32;
      d0=d1;
      d1=d2;
      d2=0;
      if (shift<32) {
	 if (shift!=0)	       // added to get MSVC to work
	    d0=(d0<<shift)|(d1>>(32-shift));
	 d1=d1<<shift;
	 flag=1;
	 shift=32-shift;
	 }
      else {
	 shift=shift-32;
	 d0=d1;
	 d1=0;
	 d0=d0<<shift;
	 flag=0;
	 shift=32-shift;
	 }
      }
   }

d0=~d0;
d1=~d1;
d2=~d2;
d3=~d3;
temp=d3+1;
c=carry(d3,1,temp);
d3=temp;

temp=d2+c;
c=carry(d2,c,temp);
d2=temp;

temp=d1+c;
c=carry(d1,c,temp);
d1=temp;

d0=d0+c;
for (i=0; i<count; i++) {
   temp3=a3+d3;
   c2=carry(a3,d3,temp3);

   temp=a2+c2;
   c1=carry(a2,c2,temp);

   temp2=temp+d2;
   c1+=carry(temp,d2,temp2);

   temp=a1+c1;
   c0=carry(a1,c1,temp);

   temp1=temp+d1;
   c0+=carry(temp,d1,temp1);

   temp0=a0+d0+c0;
   if ((temp0>>31)==0) {
      a0=temp0<<1;
      if ((temp1>>31)!=0)
	 c=1;
      else
	 c=0;
      a0=a0+c;
      a1=temp1<<1;
      if ((temp2>>31)!=0)
	 c=1;
      else
	 c=0;
      a1=a1+c;
      a2=temp2<<1;
      if ((temp3>>31)!=0)
	 c=1;
      else
	 c=0;
      a2=a2+c;
      a3=temp3<<1;
      a3=a3+1;
      }
   else {
      a0=a0<<1;
      if ((a1>>31)!=0)
	 c=1;
      else
	 c=0;
      a0=a0+c;

      a1=a1<<1;
      if ((a2>>31)!=0)
	 c=1;
      else
	 c=0;
      a1=a1+c;

      a2=a2<<1;
      if ((a3>>31)!=0)
	 c=1;
      else
	 c=0;
      a2=a2+c;

      a3=a3<<1;
      }
   }
shift=shift-1;
if (flag==3) {
   a0=0;
   a1=0;
   a2=0;
   a3=a3<<shift;
   a3=a3>>shift;
   }
else {
   if (flag==2) {
      a0=0;
      a1=0;
      a2=a2<<shift;
      a2=a2>>shift;
      }
   else {
      if (flag==1) {
	 a0=0;
	 a1=a1<<shift;
	 a1=a1>>shift;
	 }
      else {
	 a0=a0<<shift;
	 a0=a0>>shift;
	 }
      }
   }
*quotient=a0;
*(quotient+1)=a1;
*(quotient+2)=a2;
*(quotient+3)=a3;
return;
}