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