]> git.sur5r.net Git - cc65/blobdiff - libsrc/common/vfprintf.s
On Apple GEOS all "low jumptable" entries went into 'diskdrv.inc'. So this needs...
[cc65] / libsrc / common / vfprintf.s
index aed6ce16dc60f290dc164d12d4f8930ce2ede685..881bf9b4219dc72ae0c19268f8eb6f65f1821813 100644 (file)
+; vfprintf.s
 ;
-; int vfprintf (FILE* f, const char* Format, va_list ap);
-;
-; Ullrich von Bassewitz, 1.12.2000
+; int fastcall vfprintf(FILE* f, const char* Format, va_list ap);
 ;
+; 2005-02-08, Ullrich von Bassewitz
+; 2005-02-11, Greg King
 
-       .export         _vfprintf
-       .import         pushax, popax, push1
-       .import         _fwrite, __printf
-       .importzp       sp, ptr1, ptr2
+        .export                _vfprintf
+        .import                push1, pushwysp, incsp6
+        .import                _fwrite, __printf
+        .importzp              sp, ptr1
 
-       .macpack        generic
+        .macpack       generic
 
 
 .data
 
 ; ----------------------------------------------------------------------------
-;
 ; Static data for the _vfprintf routine
 ;
-
-outdesc:                       ; Static outdesc structure
-       .word   0               ; ccount
-       .word   out             ; Output function pointer
-       .word   0               ; ptr
-       .word   0               ; uns
+outdesc:                        ; Static outdesc structure
+ccount: .res   2
+        .word  out             ; Output function pointer
+ptr:    .res   2               ; Points to output file
+        .res   2               ; (Not used by this function)
 
 .code
 
 ; ----------------------------------------------------------------------------
 ; Callback routine used for the actual output.
 ;
+; Since we know, that this routine is always called with "our" outdesc, we
+; can ignore the passed pointer d, and access the data directly. While this
+; is not very clean, it gives better and shorter code.
+;
 ; static void out (struct outdesc* d, const char* buf, unsigned count)
 ; /* Routine used for writing */
 ; {
+;     register size_t cnt;
+;
 ;     /* Write to the file */
-;     if (fwrite (buf, count, 1, (FILE*) d->ptr) == -1) {
-;         d->ccount = -1;
+;     if ((cnt = fwrite(buf, 1, count, ptr)) == 0) {
+;         ccount = -1;
 ;     } else {
-;         d->ccount += count;
+;         ccount += cnt;
 ;     }
 ; }
 
-out:
-
 ; About to call
 ;
-;      fwrite (buf, count, 1, (FILE*) d->ptr);
+;       fwrite (buf, 1, count, ptr);
 ;
-; Since Buf and Count are already in place, we will just push the last
-; two parameters. The fwrite function will remove Buf and Count on exit.
-
-       jsr     push1
-       ldy     #7              ; Offset of D+1 on stack
-       lda     (sp),y
-       sta     ptr1+1
-       dey                     ; Offset of D on stack (6)
-       lda     (sp),y
-       sta     ptr1
-       dey                     ; Offset of ptr+1 in struct outdesc (5)
-       lda     (ptr1),y
-       tax
-       dey
-       lda     (ptr1),y
-       jsr     pushax          ; Push D->ptr
-       jsr     _fwrite
-               sta     ptr2            ; Save function result
-       stx     ptr2+1
-
-; Pop the last parameter from stack and store it in ptr1. This means that
-; the stack is clean now.
-
-       jsr     popax
-       sta     ptr1
-       stx     ptr1+1
-
-; Load the offset of ccount in struct outdesc
-
-       ldy     #$00
-
-; Check the return code. Checking the hig byte against $FF is ok here.
-
-               lda     ptr2+1
-       cmp     #$FF
-       bne     @Ok
-
-; We had an error. Store -1 into d->ccount
-
-       sta     (ptr1),y
-       iny
-       sta     (ptr1),y
-       rts
+out:    ldy     #5
+        jsr     pushwysp        ; Push buf
+        jsr     push1           ; Push #1
+        ldy     #7
+        jsr     pushwysp        ; Push count
+        lda     ptr
+        ldx     ptr+1   
+        jsr    _fwrite
+        sta    ptr1            ; Save function result
+        stx    ptr1+1
+
+; Check the return value.
+
+        ora     ptr1+1
+        bne    @Ok
+
+; We had an error. Store -1 into ccount
+
+.ifp02
+        lda    #<-1
+.else
+        dec    a
+.endif
+        sta     ccount
+        bne     @Done           ; Branch always
 
 ; Result was ok, count bytes written
 
-@Ok:   lda     (ptr1),y
-       add     ptr1
-       sta     (ptr1),y
-       iny
-       lda     (ptr1),y
-       adc     ptr1+1
-       sta     (ptr1),y
-       rts
+@Ok:    lda     ptr1
+        add     ccount
+        sta     ccount
+        txa
+        adc     ccount+1
+@Done:  sta     ccount+1
+        jmp     incsp6          ; Drop stackframe
 
 
 ; ----------------------------------------------------------------------------
-; Callback routine used for the actual output.
+; vfprintf - formatted output
 ;
-; int vfprintf (FILE* f, const char* format, va_list ap)
+; int fastcall vfprintf(FILE* f, const char* format, va_list ap)
 ; {
-;     struct outdesc d;
+;     static struct outdesc d = {
+;         0,
+;         out
+;     };
 ;
 ;     /* Setup descriptor */
-;     d.fout = out;
+;     d.ccount = 0;
 ;     d.ptr  = f;
 ;
 ;     /* Do formatting and output */
@@ -120,39 +107,39 @@ out:
 ;     /* Return bytes written */
 ;     return d.ccount;
 ; }
-
+;
 _vfprintf:
-       pha                     ; Save low byte of ap
+        pha                    ; Save low byte of ap
 
 ; Setup the outdesc structure
 
-       lda     #0
-       sta     outdesc
-       sta     outdesc+1       ; Clear ccount
+        lda    #0
+        sta    ccount
+        sta    ccount+1        ; Clear character-count
 
 ; Reorder the stack. Replace f on the stack by &d, so the stack frame is
 ; exactly as _printf expects it. Parameters will get dropped by _printf.
 
-       ldy     #2              ;
-       lda     (sp),y          ; Low byte of f
-       sta     outdesc+4       ;
-       lda     #<outdesc
-       sta     (sp),y
-       iny
-       lda     (sp),y          ; High byte of f
-       sta     outdesc+5
-       lda     #>outdesc
-       sta     (sp),y
+        ldy    #2
+        lda    (sp),y          ; Low byte of f
+        sta    ptr
+        lda    #<outdesc
+        sta    (sp),y
+        iny
+        lda    (sp),y          ; High byte of f
+        sta    ptr+1
+        lda    #>outdesc
+        sta    (sp),y
 
 ; Restore low byte of ap and call _printf
 
-       pla
-       jsr     __printf
+        pla
+        jsr    __printf
 
 ; Return the number of bytes written
 
-       lda     outdesc
-       ldx     outdesc+1
-       rts
+        lda    ccount
+        ldx    ccount+1
+        rts