]> git.sur5r.net Git - cc65/blobdiff - libsrc/common/vsnprintf.s
The spans do now contain the size of a span, no longer the end offset.
[cc65] / libsrc / common / vsnprintf.s
index 2e5f8a0565e070cf794195abd95a1150d36f8da4..21c358780bbf5706b1ab6233cd3c0ea57f400470 100644 (file)
@@ -4,7 +4,7 @@
 ; Ullrich von Bassewitz, 2009-09-26
 ;
 
-       .export         _vsnprintf
+       .export         _vsnprintf, vsnprintf
        .import         ldaxysp, popax, incsp2, incsp6
        .import         _memcpy, __printf
        .importzp       sp, ptr1
 ; Static data for the _vsnprintf routine
 ;
 
-outdesc:                       ; Static outdesc structure
-       .word   0               ; ccount
-       .word   out             ; Output function pointer
-       .word   0               ; ptr
-               .word   0               ; Buffer size
+outdesc:                       ; Static outdesc structure
+ccount: .word   0               ; ccount
+func:   .word   out            ; Output function pointer
+bufptr: .word   0              ; ptr
+bufsize:.word   0               ; Buffer size
 
 .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     outdesc+6               ; Low byte of buffer size
-        sec
-        sbc     outdesc+0               ; Low byte of bytes already written
-        sta     ptr1
-        lda     outdesc+7
-        sbc     outdesc+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     outdesc+0
-        clc
-        adc     outdesc+4
-        ldy     #4
-        sta     (sp),y
-
-        lda     outdesc+1
-        adc     outdesc+5
-        iny
-        sta     (sp),y
-
-; Get Count from stack
-
-        jsr     popax
-
-; outdesc.ccount += Count;
-
-        pha
-        clc
-        adc     outdesc+0
-        sta     outdesc+0
-        txa
-        adc     outdesc+1
-        sta     outdesc+1
-        pla
-
-; if (Count > Left) Count = Left;
-
-        cmp     ptr1
-        bne     @L1
-        cpx     ptr1+1
-@L1:    bcs     @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
 ;
@@ -102,13 +33,17 @@ out:
 ;
 
 _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     outdesc
-       sta     outdesc+1       ; Clear ccount
+       sta     ccount+0
+       sta     ccount+1        ; Clear ccount
 
 ; Get the size parameter and replace it by a pointer to outdesc. This is to
 ; build a stack frame for the call to _printf.
@@ -117,54 +52,60 @@ _vsnprintf:
         ldy     #2
         lda     (sp),y
         sta     ptr1
+
         lda     #<outdesc
         sta     (sp),y
+
         iny
         lda     (sp),y
         sta     ptr1+1
+
         ora     ptr1
         beq     L9
 
         lda     #>outdesc
         sta     (sp),y
 
-; Write size-1 to the outdesc structure
+; Write size-1 to outdesc.uns
 
-        ldx     ptr1
         ldy     ptr1+1
-        dex
+        ldx     ptr1
         bne     L1
         dey
-L1:     stx     outdesc+6
-        sty     outdesc+7
+L1:     dex
+        stx     bufsize+0
+        sty     bufsize+1
 
-; Copy buf to the outdesc structure
+; Copy buf to the outdesc.ptr
 
         ldy     #5
         jsr     ldaxysp
-        sta     outdesc+4
-        stx     outdesc+5
+        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     outdesc+0
-        ldx     outdesc+1
-        cpx     outdesc+7
+        lda     ccount+0
+        ldx     ccount+1
+        cpx     bufsize+1
         bne     L2
-        cmp     outdesc+6
+        cmp     bufsize+0
 L2:     bcc     L3
-        lda     outdesc+6
-        ldx     outdesc+7
+        lda     bufsize+0
+        ldx     bufsize+1
         clc
-L3:     adc     outdesc+4
+L3:     adc     bufptr+0
         sta     ptr1
         txa
-        adc     outdesc+5
+        adc     bufptr+1
         sta     ptr1+1
 
         lda     #0
@@ -173,14 +114,86 @@ L3:     adc     outdesc+4
 
 ; Return the number of bytes written and drop buf
 
-        lda     outdesc         ; ccount
-        ldx     outdesc+1
+        lda     ccount+0
+        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
+
+
+