vsnprintf_callee.asm
bitfixer_bitfixer/dg/z88dk/libsrc/stdio_new/file/vsnprintf_callee.asm
; int __CALLEE__ vsnprintf_callee(char *s, unsigned int size, const char *fmt, void *arg_ptr)
; 05.2008 aralbrec

PUBLIC vsnprintf_callee
PUBLIC ASMDISP_VSNPRINTF_CALLEE

EXTERN vfprintf_callee
EXTERN LIBDISP_VFPRINTF_CALLEE

.vsnprintf_callee

   pop hl
   pop bc
   pop de
   exx
   pop de
   pop hl
   exx
   push hl

.asmentry

   ; enter : de  = format string
   ;         bc  = & parameter list (arg_ptr)
   ;         hl' = char *s
   ;         de' = max size (including '\0')
   ; exit  : hl  = length of string generated by stream not including \0
   ;               if the destination buffer was too short not all these chars were written

   exx
   ld a,d                      ; reduce buffer size by 1 if possible for the '\0' char
   or e
   jr z, nobuffer
   dec de

   call nobuffer               ; there is a non-empty destination buffer
   exx
   ld (hl),0                   ; which means we need to add a terminating '\0'
   exx
   ret

.nobuffer

   exx

   ld ix,snprintf_outchar       ; address of 'stream' output function
   jp vfprintf_callee + LIBDISP_VFPRINTF_CALLEE

.snprintf_outchar

   ; called by vfprintf()
   ; when called the secondary register set is active
   ;
   ; enter :  c = char to write to string
   ;         hl = char *s
   ;         de = space remaining in buffer
   ; exit  : no carry to indicate no error

   ld a,d                      ; if there's no space left in buffer
   or e
   ret z                       ; return without advancing buffer ptr (to find out how many chars are actually printed)
   dec de
   
   ld (hl),c
   inc hl
   ret

defc ASMDISP_VSNPRINTF_CALLEE = # asmentry - vsnprintf_callee
