; Ullrich von Bassewitz, 2009-09-26
;
- .export _vsnprintf
+ .export _vsnprintf, vsnprintf
.import ldaxysp, popax, incsp2, incsp6
.import _memcpy, __printf
.importzp sp, ptr1
.code
-; ----------------------------------------------------------------------------
-; Callback routine used for the actual output.
-;
-; static void out (struct outdesc* d, const char* buf, unsigned count)
-; /* Routine used for writing */
-;
-; Since we know, we're called with a pointer to our static outdesc structure,
-; we don't need the pointer passed on the stack.
-
-out:
-
-; Calculate the space left in the buffer. If no space is left, don't copy
-; any characters
-
- lda bufsize ; Low byte of buffer size
- sec
- sbc ccount+0 ; Low byte of bytes already written
- sta ptr1
- lda bufsize+1
- sbc ccount+1
- sta ptr1+1
- bcs @L0 ; Space left
- lda #0
- sta ptr1
- sta ptr1+1
-
-; Replace the pointer to d by a pointer to the write position in the buffer
-; for the call to memcpy that follows.
-
-@L0: lda bufptr+0
- clc
- adc ccount+0
- ldy #4
- sta (sp),y
-
- lda bufptr+1
- adc ccount+1
- iny
- sta (sp),y
-
-; Get Count from stack
-
- jsr popax
-
-; outdesc.ccount += Count;
-
- pha
- clc
- adc ccount+0
- sta ccount+0
- txa
- adc ccount+1
- sta ccount+1
- pla
-
-; if (Count > Left) Count = Left;
-
- cpx ptr1+1
- bne @L1
- cmp ptr1
-@L1: bcc @L2
- lda ptr1
- ldx ptr1+1
-
-; Jump to memcpy, which will cleanup the stack and return to the caller
-
-@L2: jmp _memcpy
-
-
; ----------------------------------------------------------------------------
; vsprintf - formatted output into a buffer
;
;
_vsnprintf:
- pha ; Save low byte of ap
+ pha ; Save ap
+ txa
+ pha
-; Setup the outdesc structure
+; Setup the outdesc structure. This is also an additional entry point for
+; vsprintf with ap on stack
+vsnprintf:
lda #0
sta ccount+0
sta ccount+1 ; Clear ccount
ldy #2
lda (sp),y
sta ptr1
+
lda #<outdesc
sta (sp),y
+
iny
lda (sp),y
sta ptr1+1
+
ora ptr1
beq L9
; Write size-1 to outdesc.uns
- ldx ptr1
ldy ptr1+1
- dex
+ ldx ptr1
bne L1
dey
-L1: stx bufsize+0
+L1: dex
+ stx bufsize+0
sty bufsize+1
; Copy buf to the outdesc.ptr
sta bufptr+0
stx bufptr+1
-; Restore low byte of ap and call _printf
+; Restore ap and call _printf
pla
+ tax
+ pla
jsr __printf
-; Terminate the string
+; Terminate the string. The last char is either at bufptr+ccount or
+; bufptr+bufsize, whichever is smaller.
lda ccount+0
ldx ccount+1
ldx ccount+1
jmp incsp2
-; Bail out if size is zero
+; Bail out if size is zero.
-L9: lda #0
+L9: pla
+ pla ; Discard ap
+ lda #0
tax
jmp incsp6 ; Drop parameters
+; ----------------------------------------------------------------------------
+; Callback routine used for the actual output.
+;
+; static void out (struct outdesc* d, const char* buf, unsigned count)
+; /* Routine used for writing */
+;
+; Since we know, we're called with a pointer to our static outdesc structure,
+; we don't need the pointer passed on the stack.
+
+out:
+
+; Calculate the space left in the buffer. If no space is left, don't copy
+; any characters
+
+ lda bufsize+0 ; Low byte of buffer size
+ sec
+ sbc ccount+0 ; Low byte of bytes already written
+ sta ptr1
+ lda bufsize+1
+ sbc ccount+1
+ sta ptr1+1
+ bcs @L0 ; Branch if space left
+ lda #$00
+ sta ptr1
+ sta ptr1+1 ; No space left
+
+; Replace the pointer to d by a pointer to the write position in the buffer
+; for the call to memcpy that follows.
+
+@L0: lda bufptr+0
+ clc
+ adc ccount+0
+ ldy #4
+ sta (sp),y
+
+ lda bufptr+1
+ adc ccount+1
+ iny
+ sta (sp),y
+
+; Get Count from stack
+
+ jsr popax
+
+; outdesc.ccount += Count;
+
+ pha
+ clc
+ adc ccount+0
+ sta ccount+0
+ txa
+ adc ccount+1
+ sta ccount+1
+ pla
+
+; if (Count > Left) Count = Left;
+
+ cpx ptr1+1
+ bne @L1
+ cmp ptr1
+@L1: bcc @L2
+ lda ptr1
+ ldx ptr1+1
+
+; Jump to memcpy, which will cleanup the stack and return to the caller
+
+@L2: jmp _memcpy
+
+
+