#if 0C -o div32 div32.o;Exit 0#endif/* div32.c  MC68020 division routine, 64 bits over 32 bits  Created: 2012.09.29 20:24 EDT  Revised: 2012.10.02 19:46 EDT  Author:  Adam Jason Pickett12.10.02 19:16 - Signed remainder sign is now correct; simpler code.	NOTE: Baslisk II overflows in 0x40000000xxxxxxxx/0x80000000 case.12.10.02 19:02 - Whoops: rem. is _not_ supposed to reflect quotient sign!12.10.02 15:57 - Smaller code with temporary fix for bad remainder results.12.10.01 05:56 - MINEM68K compilation, final tests & bug fix for new method.12.10.01 02:xx - Param adjustments; optimizations: high-shift method.12.09.30 03:04 - Beta: low-shift method (slower).*/#include <stdio.h>/* defines and typedefs used in [Mini] vMac */#define LOCALPROC		static void#define LOCALFUNC		static/* binary */typedef unsigned char	ui3b;/* integer */typedef unsigned long	ui5r;typedef long		si5b, si5r;typedef struct ui6r{	ui5r		hi, lo;} ui6r;/* ---- code *//* performs the division of (hr:lq)/d, by type based on sign g *//* if no overflow, stores remainder:quotient in hr:lq, returns zero *//* returns 2 on divide-by-zero */LOCALFUNC int div32(ui5r *hr,	ui5r *lq,	ui5r d,	si5r g){	ui5r		hi = *hr, lo = *lq, q = 0, i = 32, r, c;	/* apply sign, raise and check high bound */	/* the mc68040 microcode is balanced U/S (both 47cc) */	/* this is the closest to the real thing */	if ((r=g)!=0) {		g = (signed)(hi^d)>>(i=31); /* sign complement */		if ((r=(signed)hi>>i)!=0) {			if ((lo=-lo)!=0) /* negate hi:lo */				++hi;			if ((signed)(hi=-hi)<0)				goto ovf; /* largest cannot fit */		}		if ((signed)d<0)			d =-d;		/* first subtraction first - closer to actual; 10.01 03:00 */		/* 9.30 implementation was more complicated */		hi+= hi, hi+= lo>>i, lo+= lo;	}	if (hi>=d) { /* highest-carry - only -0x80000000 quo passes */		if (!g || (hi-=d)!=0 || (lo>>1)>=d) {		ovf:	if (!d)				return 2; /* dbz */			return 1;		}		q = 1;	}	do { /* high-carry (#31->#32: always higher) */		q+= q, c = (signed)hi>>31, hi+= hi;		if (((hi+=lo>>31)|c)>=d)			hi-= d, ++q;	} while(lo+=lo,--i);	hi^= r, hi-= r, *hr = hi; /* sign-complemented results */	q^= g, q-= g, *lq = q;	return 0;}/* - for MINimum EMulator 68K.cLOCALPROC DoDivL(void){	ui5b		*quo, rem, err;	si4b		extra = nextiword();	si4b		rDr = extra&7;	DecodeModeRegister(mode,reg);	rem = m68k_dreg(rDr);	quo = &m68k_dreg(extra>>12&7);	if (!(extra&0x400))		rem = (si5b)((ui5b)extra<<20&*quo)>>31; // zero if not DIVS	if ((err=div32(&rem,quo,GetArgValue(),extra&0x800))!=0) {		VFLG = 1; // overflow should be set first (68040: always)		if (err==2) {			Exception(5);#if m68k_logExceptions			dbglog_StartLine();			dbglog_writeCStr("*** zero devide exception");			dbglog_writeReturn();#endif		}#if EmCPU<4 //68040 only sets V, does nothing else; not sure about 020/030		NFLG = 1, CFLG = 0;#endif		return;	}	m68k_dreg(rDr) = rem;	NFLG = (signed)*quo<0;	ZFLG = *quo==0;	VFLG = CFLG = 0;}*//* extended version of atoll (so stdlib.h isn't required) *//* returns 1 if non-negative, -1 if negative, 0 on error */LOCALFUNC int readanyint64(const char *s,	ui6r *v){	ui6r		r;	ui5r		t, g = 0;	ui3b		c;	if (!s || (c=*s++)==0)		return 0;	while(*s==' ' || *s=='\t')		++s; /* skip whitespace */	r.hi = r.lo = 0;	if ((c+=-'-')==0) {		g =-1;		if ((c=*s++)==0)			return 0;	} else if ((c+='-'-'+')==0) {		if ((c=*s++)==0)			return 0;	} else if ((ui3b)((c+='+')-'0')>(ui3b)('9'-'0'))		return 0;	if (c!='0') {		do {		decimal:			c-= '0';			if (c>(ui3b)9)				if ((c+='0'-'A')<=(ui3b)('Z'-'A')						|| (c+='A'-'a')<=(ui3b)('z'-'a')						|| (c+='a'-'_')==0)					return 0;				else					break;			r.hi = r.hi<<1|r.lo>>31, r.lo+= r.lo; /* r<<= 1 */			r.hi+= r.hi<<2|r.lo>>30, t = r.lo; /* r+= r<<2 */			if ((r.lo+=r.lo<<2)<t)				++r.hi;			t = r.lo;			if ((r.lo+=c)<t) /* r+= c */				++r.hi;		} while((c=*s++)!=0);		goto end;	}	if ((c=*s++)==0)		goto end; /* zero */	if (c!='x' && c!='X') {		if ((ui3b)(c-'0')<8) { /* octal */			 do {				c-= '0';				if (c>(ui3b)7)					if (c<=(ui3b)('9'-'7')							|| (c+='0'-'A')<=(ui3b)('Z'-'A')							|| (c+='A'-'a')<=(ui3b)('z'-'a')							|| (c+='a'-'_')==0)						return 0;					else						break;				r.hi = r.hi<<3|r.lo>>29, r.lo = r.lo<<3|c;			} while((c=*s++)!=0);			goto end;		}		if (c=='b' || c=='B') { /* binary */			if ((c=*s++)==0)				return 0; /* no digits */			do {				c-= '0';				if (c>(ui3b)1)					if (c<=(ui3b)('9'-'1')							|| (c+='0'-'A')<=(ui3b)('Z'-'A')							|| (c+='A'-'a')<=(ui3b)('z'-'a')							|| (c+='a'-'_')==0)						return 0;					else						break;				r.hi = r.hi<<1|r.lo>>31, r.lo = r.lo<<1|c;			} while((c=*s++)!=0);			goto end;		}		goto decimal;	}	if ((c=*s++)==0)		return 0; /* no digits */	do {		c-= '0';		if (c<=(ui3b)('9'-'0'))			goto hdig;		else if ((c+='0'-'A')<=(ui3b)('Z'-'A')				|| (c+='A'-'a')<=(ui3b)('z'-'a'))			if (c>(ui3b)('F'-'A'))				return 0;			else {				c+= 10;			hdig:	r.hi = r.hi<<4|r.lo>>28, r.lo = r.lo<<4|c;			}		else if ((c+='a'-'_')==0)			return 0;		else			break;	} while((c=*s++)!=0);end:	if (v) { /* apply sign */		r.hi^= g, t = r.lo^= g;		if ((r.lo-=g)>t)			--r.hi;		r.hi-= g;		*v = r;	}	return g|1;}main(int argc,	char const*const*argv){	char		const*const*a;	ui6r		n;	si5b		d, g, t;	if (argc<=0 || (a=argv)==0)		return 0;	if (!--argc) {		fprintf(stderr,"# form: %s <numer.s64> <denom.s32 | 1>\n",			*a);		return 1;	}	d = 1, g = 0; /* default */	if (--argc) {		if ((g=readanyint64(a[2],&n))==0)			{++a; goto bad;}		d = n.lo;	}	if ((t=readanyint64(argv[1],&n))==0) {	bad:	fprintf(stderr,"### %s - invalid numeric (%s)\n",			*argv,a[1]);		return 1;	}	g|= t;	printf("# %016llX /%s %08X\n",		n,(g&=2) ? "/":"",d);	fflush(stdout);	if ((d=div32(&n.hi,&n.lo,d,g))!=0)		fprintf(stderr,"## %s - overflow (%d)\n",			*argv,d);	printf("# rem %08X, quo %08X -- #%u or #%d\n",		n.hi,n.lo,n.lo,n.lo);	return 0;}