2 ; Ullrich von Bassewitz, 2002-11-22, 2004-05-14
4 ; size_t __fastcall__ fread (void* buf, size_t size, size_t count, FILE* file);
5 ; /* Read from a file */
11 .import pusha0, pushax
12 .import incsp4, incsp6
13 .import ldaxysp, ldax0sp
15 .import tosumulax, tosudivax
24 ; ------------------------------------------------------------------------
29 ; We will place a pointer to the file descriptor into the register bank
34 ; Save two bytes from the register bank
41 ; Save the file pointer into the register bank
46 ; Check if the file is open
50 and #_FOPEN ; Is the file open?
51 beq @L1 ; Branch if no
53 ; Check if the stream is in an error state
55 lda (file),y ; get file->f_flags again
59 ; File not open or in error state
62 jsr __seterrno ; Set __errno, return zero in A
66 ; Remember if we have a pushed back character and reset the flag.
74 sta (file),y ; file->f_flags &= ~_FPUSHBACK;
78 ; Build the stackframe for read()
82 jsr pusha0 ; file->f_fd
87 ; Stack is now: buf/size/count/file->fd/buf
88 ; Calculate the number of bytes to read: count * size
93 jsr ldaxysp ; Get size
94 jsr tosumulax ; count * size -> a/x
96 ; Check if count is zero.
103 ; Count is zero, drop the stack frame just built and return count
105 jsr incsp4 ; Drop file->fd/buf
106 jsr ldax0sp ; Get count
109 ; Check if we have a buffered char from ungetc
114 ; We have a buffered char from ungetc. Save the low byte from count
118 ; Copy the buffer pointer into ptr1, and increment the pointer value passed
119 ; to read() by one, so read() starts to store data at buf+1.
130 sta (sp),y ; ptr1 = buf++;
132 ; Get the buffered character and place it as first character into the read
135 ldy #_FILE::f_pushback
138 sta (ptr1),y ; *buf = file->f_pushback;
140 ; Restore the low byte of count and decrement count by one. This may result
141 ; in count being zero, so check for that.
152 ; Call read(). This will leave the original 3 params on the stack
156 ; Check for errors in read
163 ; Error in read. Set the stream error flag and bail out. errno has already
164 ; been set by read(). On entry to label @L7, X must be zero.
168 @L7: ldy #_FILE::f_flags ; X must be zero here!
172 beq @L99 ; Return zero
174 ; Read was ok, account for the pushed back character (if any).
180 ; Check for end of file.
182 @L9: cmp #0 ; Zero bytes read?
187 ; Zero bytes read. Set the EOF flag
190 bne @L7 ; Set flag and return zero
192 ; Return the number of items successfully read. Since we've checked for
193 ; bytes == 0 above, size cannot be zero here, so the division is safe.
195 @L10: jsr pushax ; Push number of bytes read
197 jsr ldaxysp ; Get size
198 jsr tosudivax ; bytes / size -> a/x
199 @L99: ldy save ; Restore zp register
203 jmp incsp6 ; Drop params, return
207 ; ------------------------------------------------------------------------