
		section	test_printf,code	;use publicmem

ProgStart	bsr.b	_PrintInit		;initialise printf
		beq.s	Quit			;failed?

		lea	hello(pc),a0		;format string
		lea	hello.arg(pc),a1	;arguments string
		bsr.b	printf

		bsr.b	_PrintClose		;free printf memory
quit		rts

hello		dc.b	"Hello, %ld World!",10,0
		even
hello.arg	dc.l	911
		even

AbsExecBase	=	$4
MEMF_CLEAR	=	$10000
MEMF_PUBLIC	=	$1

_LVOFreeMem	=	-$D2
_LVORawPutChar	=	-$204
_LVORawDoFmt	=	-$20A
_LVOOutput	=	-$3C
_LVOWrite	=	-$30
_LVOOldOpenLibrary	=	-$198
_LVOAllocMem	=	-$C6
_LVORawIOInit	=	-$1F8

*****************************************************************************
* PrintInit( )
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Inputs:	None.
* $Outputs:	d0.l=0 if failed.. 
*
* Initializes further usage of Print( ) function.
* Gets output handle, calls AllocMem() for 127 byte output buffer, and
* RawIOInit().  Preserves all registers used.  This should be placed
* in your "opening" routine before any printf() calls.
* D0 will contain a non-zero value ( Z = 0 ) if AllocMem() was successful,
* otherwise D0 = 0 ( Z = 1 ) on return if failure.
*
* ( If PrintInit() fails, you don't need to quit.  Print( ) and can tell that 
* the allocation failed and will return without doing anything. )
******************************************************************************

_PrintInit:	movem.l	d0/d1/a0/a1/a4/a6,-(sp)
		lea	_DOSBase(pc),a4
		move.l	(AbsExecBase).w,a6
		lea	DosName(pc),a1
		jsr	_LVOOldOpenLibrary(a6)		;open dos library
		move.l	d0,(a4)
		beq.s	_NoPrintInit
		move.l	d0,a6
		jsr	_LVOOutput(a6)			;get output base
		move.l	d0,_DosOutput-_DOSBase(a4)

		move.l	(AbsExecBase).w,a6
		moveq	#127,d0
		move.l	#(MEMF_PUBLIC+MEMF_CLEAR),d1
		jsr	_LVOAllocMem(a6)		;allocate 127 bytes
		move.l	d0,_MemPtr1-_DOSBase(a4)
		jsr	_LVORawIOInit(a6)		;do a raw IO init
_NoPrintInit:	movem.l	(sp)+,d0/d1/a0/a1/a4/a6
		rts

******************************************************************************
* PrintClose( )
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
*
* If AllocMem() from PrintInit( ) was successful, this does a FreeMem()
* freeing the 127 byte output buffer.  Preserves all registers used.
* This should be placed in your "closing" routine after last printf() call.
******************************************************************************

_PrintClose:	movem.l	d0/d1/a0/a1/a6,-(sp)
		lea	_MemPtr1(pc),a1
		tst.l	(a1)
		beq.s	_NoPrintClose
		move.l	(a1),a1
		moveq	#127,d0
		move.l	(AbsExecBase).w,a6
		jsr	_LVOFreeMem(a6)			;free raw io memory

_NoPrintClose:	movem.l	(sp)+,d0/d1/a0/a1/a6
		rts

******************************************************************************
* Usage:  printf( FormatString DataStream )
*                   A0            A1
*
* Performs "C" language like formatting of the data stream. Where % formatting
* cmd`s are found in FormatString, they're replaced with the corresponding 
* element in the DataStream.
*
* Printf() outputs the results to the current output handle, usually the CLI.
********************************************************************************

printf:		movem.l	d0-d3/a0-a3/a6,-(sp)
		lea	PrintChar(pc),a2
		tst.l	_MemPtr1-PrintChar(a2)
		beq.s	_NoPrint

		move.l	(AbsExecBase).w,a6
		move.l	_MemPtr1(pc),a3
		jsr	_LVORawDoFmt(a6)

		move.l	_DOSBase(pc),a6
		move.l	_DosOutput(pc),d1
		move.l	_MemPtr1(pc),d2

		move.l	_MemPtr1(pc),a3
		moveq	#-1,d3
getlen		addq.l	#1,d3
		tst.b	(a3)+
		bne.s	getlen
		jsr	_LVOWrite(a6)

_NoPrint:	movem.l	(sp)+,d0-d3/a0-a3/a6
		rts
PrintChar:	move.b	d0,(a3)+
		rts

DosName:	dc.b	'dos.library',0
		even
_DOSBase:	dc.l	0
_MemPtr1:	dc.l	0
_DosOutput:	dc.l	0

		end
