]> git.sur5r.net Git - cc65/blob - libsrc/common/fread.s
Renamed one letter label
[cc65] / libsrc / common / fread.s
1 ;
2 ; Ullrich von Bassewitz, 22.11.2002
3 ;
4 ; size_t __fastcall__ fread (void* buf, size_t size, size_t count, FILE* file);
5 ; /* Read from a file */
6 ;
7
8         .export         _fread
9
10         .import         _read
11         .import         pushax, incsp6, addysp, ldaxysp, pushwysp, return0
12         .import         tosumulax, tosudivax
13
14         .importzp       ptr1, tmp1
15
16         .include        "errno.inc"
17         .include        "_file.inc"
18
19
20 ; ------------------------------------------------------------------------
21 ; Code
22
23 .proc   _fread
24
25 ; Save file and place it into ptr1
26
27         sta     file
28         sta     ptr1
29         stx     file+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 file->f_flags again
51         and     #_FERROR
52         bne     @L1
53
54 ; Build the stackframe for read()
55
56         ldy     #_FILE_f_fd
57         lda     (ptr1),y
58         ldx     #$00
59         jsr     pushax                  ; file->f_fd
60
61         ldy     #9
62         jsr     pushwysp                ; buf
63
64 ; Stack is now: buf/size/count/file->fd/buf
65 ; Calculate the number of bytes to read: 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 read in this case
74
75         cpx     #0
76         bne     @L3
77         cmp     #0
78         bne     @L3
79
80 ; The number of bytes to read 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 read(). This will leave the original 3 params on the stack
88
89 @L3:    jsr     _read
90
91 ; Check for errors in read
92
93         cpx     #$FF
94         bne     @L5
95         cmp     #$FF
96         bne     @L5
97
98 ; Error in read. Set the stream error flag and bail out. _oserror and/or
99 ; errno are already set by read().
100
101         lda     #_FERROR
102 @L4:    sta     tmp1
103         lda     file
104         sta     ptr1
105         lda     file+1
106         sta     ptr1+1
107         ldy     #_FILE_f_flags
108         lda     (ptr1),y
109         ora     tmp1
110         sta     (ptr1),y
111         bne     @L1                     ; Return zero
112
113 ; Read was ok, check for end of file.
114
115 @L5:    cmp     #0                      ; Zero bytes read?
116         bne     @L6
117         cpx     #0
118         bne     @L6
119
120 ; Zero bytes read. Set the EOF flag
121
122         lda     #_FEOF
123         bne     @L4                     ; Set flag and return zero
124
125 ; Return the number of items successfully read. Since we've checked for
126 ; bytes == 0 above, size cannot be zero here, so the division is safe.
127
128 @L6:    jsr     pushax                  ; Push number of bytes read
129         ldy     #5
130         jsr     ldaxysp                 ; Get size
131         jsr     tosudivax               ; bytes / size -> a/x
132         jmp     incsp6                  ; Drop params, return
133
134 .endproc
135
136 ; ------------------------------------------------------------------------
137 ; Data
138
139 .bss
140 file:   .res    2
141