include mc.ash
.model small
;
;Support routines for PRINTF.C
;
;Tom Jennings
;22 Jan 92
;
.code
;/*
;	Internal routine used by "_spr" to perform ascii-
;	to-decimal conversion and update an associated pointer:
;*/
;
;int _gv2(sptr)
;char **sptr;
;{
;int n;
;	n = 0;
;	while (isdigit(**sptr)) n = 10 * n + *(*sptr)++ - '0';
;	return(n);
;}
func __gv2
	push	si
	mov	si,arg0		;SI= *sptr
	mov	bx,[si]		;BX= sptr
	mov	dx,0		;N= 0
	mov	ah,0

gv1:	mov	al,[bx]		;AL= *sptr
	sub	al,'0'		;
	jc	gvz		; < '0'
	cmp	al,10
	jnc	gvz		; > '9'

	add	dx,dx		; N *= 2
	mov	cx,dx		; (save that)
	add	dx,dx		; N *= 4
	add	dx,dx		; N *= 8
	add	dx,cx		; N *= 10
	add	dx,ax		; + digit
	inc	bx
	jmp	gv1

gvz:	mov	[si],bx
	pop	si
	mov	ax,dx
endf __gv2


;static char itoctbl[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
;
;_uspr(buff, n, base)
;char buff[];
;long n;
;unsigned base;
;{
;unsigned length;
;
;	if ((n < base) && (n >= 0L)) {
;		*buff++= itoctbl[n];
;		+buff= '\0';
;		return(1);
;	}
;	length = _uspr(buff, (long)(n / base), base);
;	_uspr(buff, (long)(n % base), base);
;	return (length + 1);
;}
;
itoctbl db "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
;NOTES: 'n' is long, and treated explicitly for testing
;as two 16 bit ints. For speed, *buff is converted to
;buff in DI, and not passed on the stack.
;
;      arg0  arg1 & 2   arg3
;_uspr(buff, n,         base)
;
func __uspr
	push	si
	push	di
	mov	di,arg0		;(avoid mult.
	mov	di,[di]		;indirection)
	cld			;DI= buff
	mov	si,0		;SI= length
	mov	ax,arg1
	mov	dx,arg2		;AX:DX= n
	mov	cx,arg3		;CX= base
	call	_uspr		;do it

	mov	bx,arg0
	mov	[bx],di		;set buff
	mov	ax,si		;return length
	pop	di
	pop	si
endf __uspr

_uspr:
	or	dx,dx
	jnz	uu1
	cmp	ax,cx		;n < base?
	jnc	uu1
	mov	bx,ax
	mov	al,cs:itoctbl[bx]
	stosb			;*buff++= char
	mov	ax,bx		;(restore LSB n)
	inc	si		;++length
	ret

uu1:	div	cx		;AX=q DX=rem
	push	dx
	mov	dx,0
	call	_uspr		;uspr(n / 10)
	pop	ax
	mov	dx,0		;AX:DX= remainder
	jmp	_uspr		;last digit

	end

