]> git.sur5r.net Git - cc65/blob - libsrc/common/fwrite.s
Rewrote fread in assembler
[cc65] / libsrc / common / fwrite.s
1 ;
2 ; Ullrich von Bassewitz, 22.11.2002
3 ;
4 ; size_t __fastcall__ fwrite (const void* buf, size_t size, size_t count, FILE* f);
5 ; /* Write to a file */
6 ;
7
8         .export         _fwrite
9
10         .import         _write
11         .import         pushax, incsp6, addysp, ldaxysp, pushwysp, return0
12         .import         tosumulax, tosudivax
13
14         .importzp       ptr1
15
16         .include        "errno.inc"
17         .include        "_file.inc"
18
19
20 ; ------------------------------------------------------------------------
21 ; Code
22
23 .proc   _fwrite
24
25 ; Save f and place it into ptr1
26
27         sta     f
28         sta     ptr1
29         stx     f+1
30         stx     ptr1+1
31
32 ; Check if the file is open
33
34         ldy     #_FILE_f_flags
35         lda     (ptr1),y
36         and     #_FOPEN                 ; Is the file open?
37         bne     @L2                     ; Branch if yes
38
39 ; File not open
40
41         lda     #EINVAL
42         sta     __errno
43         lda     #0
44         sta     __errno+1
45 @L1:    jsr     incsp6
46         jmp     return0
47
48 ; Check if the stream is in an error state
49
50 @L2:    lda     (ptr1),y                ; get f->f_flags again
51         and     #_FERROR
52         bne     @L1
53
54 ; Build the stackframe for write()
55
56         ldy     #_FILE_f_fd
57         lda     (ptr1),y
58         ldx     #$00
59         jsr     pushax                  ; f->f_fd
60
61         ldy     #9
62         jsr     pushwysp                ; buf
63
64 ; Stack is now: buf/size/count/f->fd/buf
65 ; Calculate the number of bytes to write: count * size
66
67         ldy     #7
68         jsr     pushwysp                ; count
69         ldy     #9
70         jsr     ldaxysp                 ; Get size
71         jsr     tosumulax               ; count * size -> a/x
72
73 ; Check if the number of bytes is zero. Don't call write in this case
74
75         cpx     #0
76         bne     @L3
77         cmp     #0
78         bne     @L3
79
80 ; The number of bytes to write is zero, just return count
81
82         ldy     #5
83         jsr     ldaxysp                 ; Get count
84         ldy     #10
85         jmp     addysp                  ; Drop params, return
86
87 ; Call write(). This will leave the original 3 params on the stack
88
89 @L3:    jsr     pushax
90         jsr     _write
91
92 ; Check for errors in write
93
94         cpx     #$FF
95         bne     @L4
96         cmp     #$FF
97         bne     @L4
98
99 ; Error in write. Set the stream error flag and bail out. _oserror and/or
100 ; errno are already set by write().
101
102         lda     f
103         sta     ptr1
104         lda     f+1
105         sta     ptr1+1
106         ldy     #_FILE_f_flags
107         lda     (ptr1),y
108         ora     #_FERROR
109         sta     (ptr1),y
110         bne     @L1                     ; Return zero
111
112 ; Write was ok. Return the number of items successfully written. Since we've
113 ; checked for bytes == 0 above, size cannot be zero here, so the division is
114 ; safe.
115
116 @L4:    jsr     pushax                  ; Push number of bytes written
117         ldy     #5
118         jsr     ldaxysp                 ; Get size
119         jsr     tosudivax               ; bytes / size -> a/x
120         jmp     incsp6                  ; Drop params, return
121
122 .endproc
123
124 ; ------------------------------------------------------------------------
125 ; Data
126
127 .bss
128 f:      .res    2
129