* ------------------------------------------------------------------------- *
* Aprintf.asm
* Copyright Justin V. McCormick 1988
* ------------------------------------------------------------------------- *
	TTL	aprintf.asm

	SECTION	aprintf,CODE

	NOLIST
	include "macros.i"

;	include "libraries/dos_lib.i"
;	include	"exec/exec_lib.i"

* Equates replacing above files includes
_LVORawDoFmt	EQU	$FFFFFDF6
_LVOWrite	EQU	$FFFFFFD0

	LIST

* Externals
	XREF	_cliout		;CLI standard output filehandle, LONG
	XREF	_DOSBase	;Pointer to DOSBase, LONG
* ------------------------------------------------------------------------- *
* void aprintf(formatstring, args)
*   char *formatstring;
*   char **args;
* 
* Synopsis: Given formatstring and args to format, prints output to current
* terminal output channel, globally defined as _cliout, where:
* 
*   LONG cliout;
*   cliout = Output();
*   
* No error checking is performed for cliout pointing to a valid filehandle,
* i.e., you must initialize cliout before calling aprintf().  _DOSBase must
* be initialized as:
*   struct DOSBase *DOSBase;
*   DOSBase = (struct DOSBase *)OpenLibrary("dos.library", 33L);
* ------------------------------------------------------------------------- *
	XDEF	_aprintf
_aprintf:
	link	a5,#-512		;Allocate 512 bytes on stack
	movem.l	d0/d1/a0-a3,-(sp)	;Save everything we might clobber

* Call format function to convert fmtstring and args to buffer on the stack
	movea.l	8(a5),a0		;Grab format string
	lea	12(a5),a1		;Grab EA of arguments
	lea	kput1(pc),a2		;Grab EA of output subroutine
	lea	-512(a5),a3		;Grab EA of temp workspace
	SYS	RawDoFmt,4		;Format it into workspace

* Calculate length of resulting string, output to console CLI
	lea	-512(a5),a0		;a0 = Start of buffer
	move.l	a0,d2			;Copy for output
	bsr.s	astrlen			;Calculate string length
	move.l	d0,d3			;length of string
	move.l	_cliout,d1		;Filehandle
	SYS	Write,_DOSBase		;Dump the string to stdout
	
	movem.l	(sp)+,d0/d1/a0-a3	;Restore registers
	unlk	a5			;And stack frame
	rts

* ------------------------------------------------------------------------- *
* RawDoFmt() output routine for aprintf, called for each formatted char.
* Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
* ------------------------------------------------------------------------- *
	XDEF	kput1
kput1:
	move.b	d0,(a3)+
	rts

* ------------------------------------------------------------------------- *
* LONG astrlen(string)
*  d0            a0
*   char *string;
*
* Synopsis: Calculate length of null-byte terminated string.
* 
* Modifies: d0 = length of string, a0 = next byte address after zero byte.
* ------------------------------------------------------------------------- *
	XDEF	astrlen
astrlen:
	moveq	#0,d0		;Clear count
1$
	tst.b	(a0)+		;Test a byte for zero-ness
	 beq.s	2$		;Found it! return length
	
	addq.w	#1,d0		;Otherwise bump count
	 bra.s	1$		;Check next byte

2$
	rts

* ------------------------------------------------------------------------- *
	END
