]> git.sur5r.net Git - cc65/blob - libsrc/cbm/read.s
Finally: Commodore file I/O
[cc65] / libsrc / cbm / read.s
1 ;
2 ; Ullrich von Bassewitz, 16.11.2002
3 ;
4 ; int read (int fd, void* buf, unsigned count);
5 ;
6
7         .export         _read
8         .constructor    initstdin
9
10         .import         popax
11         .import         __errno, __oserror
12         .importzp       ptr1, ptr2, ptr3, tmp1, tmp2
13
14         .include        "errno.inc"
15         .include        "fcntl.inc"
16         .include        "cbm.inc"
17         .include        "filedes.inc"
18
19
20 ;--------------------------------------------------------------------------
21 ; initstdin: Open the stdin file descriptors for the keyboard
22
23 .proc   initstdin
24
25         lda     #LFN_READ
26         sta     fdtab+STDIN_FILENO
27         lda     #STDIN_FILENO + LFN_OFFS
28         ldx     #CBMDEV_KBD
29         stx     unittab+STDIN_FILENO
30         ldy     #$FF
31         jsr     SETLFS
32         jmp     OPEN            ; Will always succeed
33
34 .endproc
35
36 ;--------------------------------------------------------------------------
37 ; _read
38
39
40 .proc   _read
41
42 ; Retrieve count
43
44         jsr     popax           ; Get count
45         eor     #$FF
46         sta     ptr1
47         txa
48         eor     #$FF
49         sta     ptr1+1          ; Remember -count-1
50
51 ; Retrieve buf
52
53         jsr     popax
54         sta     ptr2
55         stx     ptr2+1
56
57 ; Retrieve the handle
58
59         jsr     popax
60
61 ; Check if we have a valid handle
62
63         cpx     #$00
64         bne     invalidfd
65         cmp     #MAX_FDS        ; Is it valid?
66         bcs     invalidfd       ; Jump if no
67
68 ; Check if the LFN is valid and the file is open for writing
69
70         adc     #LFN_OFFS       ; Carry is already clear
71         tax
72         lda     fdtab-LFN_OFFS,x; Get flags for this handle
73         and     #LFN_READ       ; File open for writing?
74         beq     notopen
75
76 ; Valid lfn. Make it the input file
77
78         jsr     CHKIN
79         bcs     error
80
81 ; Clear the byte counter
82
83         lda     #$00
84         sta     ptr3
85         sta     ptr3+1
86
87 ; Read the status to check if we are already at the end of the file
88         
89         jsr     READST
90         and     #%01000000
91         bne     done
92
93 ; Go looping...
94
95         beq     deccount        ; Branch always
96
97 ; Read the next byte
98
99 loop:   jsr     BASIN
100         sta     tmp1            ; Save the input byte
101
102         jsr     READST          ; Read the IEEE status
103         sta     tmp2            ; Save it
104         and     #%10111111      ; Check anything but the EOI bit
105         bne     error5          ; Assume device not present
106
107 ; Store the byte just read
108
109         ldy     #0
110         lda     tmp1
111         sta     (ptr2),y
112         inc     ptr2
113         bne     @L1
114         inc     ptr2+1          ; *buf++ = A;
115
116 ; Increment the byte count
117
118 @L1:    inc     ptr3
119         bne     @L2
120         inc     ptr3+1
121
122 ; Get the status again and check the EOI bit
123
124 @L2:    lda     tmp2
125         and     #%01000000      ; Check for EOI
126         bne     done            ; Jump if end of file reached
127
128 ; Decrement the count
129
130 deccount:
131         inc     ptr1
132         bne     loop
133         inc     ptr1+1
134         bne     loop
135
136 ; Read done, close the input channel
137
138 done:   jsr     CLRCH
139
140 ; Return the number of chars read
141
142         lda     ptr3
143         ldx     ptr3+1
144         rts
145
146 ; Error entry, file descriptor is invalid
147
148 invalidfd:
149         lda     #EINVAL
150         sta     __errno
151         lda     #0
152         sta     __errno+1
153         beq     errout
154
155 ; Error entry, file is not open
156
157 notopen:
158         lda     #3              ; File not open
159         bne     error
160
161 ; Error entry, status not ok
162
163 error5: lda     #5              ; Device not present
164 error:  sta     __oserror
165 errout: lda     #$FF
166         tax                     ; Return -1
167         rts
168
169 .endproc
170
171
172
173