+++ /dev/null
-/*
- * fwrite.c
- *
- * Ullrich von Bassewitz, 04.06.1998
- */
-
-
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include "_file.h"
-
-
-
-size_t fwrite (const void* buf, size_t size, size_t count, FILE* f)
-{
- int bytes;
-
- /* Is the file open? */
- if ((f->f_flags & _FOPEN) == 0) {
- _errno = EINVAL; /* File not open */
- return 0;
- }
-
- /* Did we have an error */
- if ((f->f_flags & _FERROR) != 0) {
- /* Cannot write to stream */
- return 0;
- }
-
- /* How many bytes to write? */
- bytes = size * count;
-
- if (bytes) {
- /* Write the data. */
- if (write (f->f_fd, buf, bytes) == -1) {
- /* Write error */
- f->f_flags |= _FERROR;
- return 0;
- }
- }
-
- /* Don't waste time with expensive calculations, assume the write was
- * complete and return the count of items.
- */
- return count;
-}
-
-
-
--- /dev/null
+;
+; Ullrich von Bassewitz, 22.11.2002
+;
+; size_t __fastcall__ fwrite (const void* buf, size_t size, size_t count, FILE* f);
+; /* Write to a file */
+;
+
+ .export _fwrite
+
+ .import _write
+ .import pushax, incsp6, addysp, ldaxysp, pushwysp, return0
+ .import tosumulax, tosudivax
+
+ .importzp ptr1
+
+ .include "errno.inc"
+ .include "_file.inc"
+
+
+; ------------------------------------------------------------------------
+; Code
+
+.proc _fwrite
+
+; Save f and place it into ptr1
+
+ sta f
+ sta ptr1
+ stx f+1
+ stx ptr1+1
+
+; Check if the file is open
+
+ ldy #_FILE_f_flags
+ lda (ptr1),y
+ and #_FOPEN ; Is the file open?
+ bne @L2 ; Branch if yes
+
+; File not open
+
+ lda #EINVAL
+ sta __errno
+ lda #0
+ sta __errno+1
+@L1: jsr incsp6
+ jmp return0
+
+; Check if the stream is in an error state
+
+@L2: lda (ptr1),y ; get f->f_flags again
+ and #_FERROR
+ bne @L1
+
+; Build the stackframe for write()
+
+ ldy #_FILE_f_fd
+ lda (ptr1),y
+ ldx #$00
+ jsr pushax ; f->f_fd
+
+ ldy #9
+ jsr pushwysp ; buf
+
+; Stack is now: buf/size/count/f->fd/buf
+; Calculate the number of bytes to write: count * size
+
+ ldy #7
+ jsr pushwysp ; count
+ ldy #9
+ jsr ldaxysp ; Get size
+ jsr tosumulax ; count * size -> a/x
+
+; Check if the number of bytes is zero. Don't call write in this case
+
+ cpx #0
+ bne @L3
+ cmp #0
+ bne @L3
+
+; The number of bytes to write is zero, just return count
+
+ ldy #5
+ jsr ldaxysp ; Get count
+ ldy #10
+ jmp addysp ; Drop params, return
+
+; Call write(). This will leave the original 3 params on the stack
+
+@L3: jsr pushax
+ jsr _write
+
+; Check for errors in write
+
+ cpx #$FF
+ bne @L4
+ cmp #$FF
+ bne @L4
+
+; Error in write. Set the stream error flag and bail out. _oserror and/or
+; errno are already set by write().
+
+ lda f
+ sta ptr1
+ lda f+1
+ sta ptr1+1
+ ldy #_FILE_f_fd
+ lda (ptr1),y
+ ora #_FERROR
+ sta (ptr1),y
+ bne @L1 ; Return zero
+
+; Write was ok. Return the number of items successfully written. Since we've
+; checked for bytes == 0 above, size cannot be zero here, so the division is
+; safe.
+
+@L4: jsr pushax ; Push number of bytes written
+ ldy #5
+ jsr ldaxysp ; Get size
+ jsr tosudivax ; bytes / size -> a/x
+ jmp incsp6 ; Drop params, return
+
+.endproc
+
+; ------------------------------------------------------------------------
+; Data
+
+.bss
+f: .res 2
+