]> git.sur5r.net Git - cc65/blob - libsrc/cbm/read.s
Merge pull request #122 from groessler/a5200
[cc65] / libsrc / cbm / read.s
1 ;
2 ; 2002-11-16, Ullrich von Bassewitz
3 ; 2013-12-23, Greg King
4 ;
5 ; int read (int fd, void* buf, unsigned count);
6 ;
7
8         .export         _read
9         .constructor    initstdin
10
11         .import         SETLFS, OPEN, CHKIN, BASIN, CLRCH, BSOUT, READST
12         .import         rwcommon
13         .import         popax
14         .importzp       ptr1, ptr2, ptr3, tmp1, tmp2, tmp3
15
16         .include        "cbm.inc"
17         .include        "errno.inc"
18         .include        "fcntl.inc"
19         .include        "filedes.inc"
20
21
22 ;--------------------------------------------------------------------------
23 ; initstdin: Open the stdin file descriptors for the keyboard
24
25 .segment        "INIT"
26
27 .proc   initstdin
28
29         lda     #LFN_READ
30         sta     fdtab+STDIN_FILENO
31         lda     #STDIN_FILENO + LFN_OFFS
32         ldx     #CBMDEV_KBD
33         stx     unittab+STDIN_FILENO
34         ldy     #$FF
35         jsr     SETLFS
36         jmp     OPEN            ; Will always succeed
37
38 .endproc
39
40 ;--------------------------------------------------------------------------
41 ; _read
42
43 .code
44
45 .proc   _read
46
47         jsr     rwcommon        ; Pop params, check handle
48         bcs     invalidfd       ; Invalid handle
49
50 ; Check if the LFN is valid and the file is open for writing
51
52         adc     #LFN_OFFS       ; Carry is already clear
53         tax
54         lda     fdtab-LFN_OFFS,x; Get flags for this handle
55         tay
56         and     #LFN_READ       ; File open for writing?
57         beq     invalidfd
58
59 ; Check the EOF flag. If it is set, don't read anything
60
61         tya                     ; Get flags again
62         bmi     eof
63
64 ; Remember the device number.
65
66         ldy     unittab-LFN_OFFS,x
67         sty     unit
68
69 ; Valid lfn. Make it the input file
70
71         jsr     CHKIN
72         bcc     @L3             ; Branch if ok
73         jmp     __mappederrno   ; Store into __oserror, map to errno, return -1
74
75 ; Read the next byte
76
77 @L0:    jsr     BASIN
78         sta     tmp1            ; Save the input byte
79         ldx     unit
80         bne     @L0_1           ; Not keyboard/screen-editor
81         cmp     #$0D            ; Is it a Carriage Return?
82         bne     @L0_1
83         jsr     BSOUT           ; Yes, echo it (because editor didn't)
84
85 @L0_1:  jsr     READST          ; Read the IEEE status
86         sta     tmp3            ; Save it
87         and     #%10111111      ; Check anything but the EOI bit
88         bne     devnotpresent   ; Assume device not present
89
90 ; Store the byte just read
91
92         ldy     #0
93         lda     tmp1
94         sta     (ptr2),y
95         inc     ptr2
96         bne     @L1
97         inc     ptr2+1          ; *buf++ = A;
98
99 ; Increment the byte count
100
101 @L1:    inc     ptr3
102         bne     @L2
103         inc     ptr3+1
104
105 ; Get the status again and check the EOI bit
106
107 @L2:    lda     tmp3
108         and     #%01000000      ; Check for EOI
109         bne     @L4             ; Jump if end of file reached
110
111 ; Decrement the count
112
113 @L3:    inc     ptr1
114         bne     @L0
115         inc     ptr1+1
116         bne     @L0
117         beq     done            ; Branch always
118
119 ; Set the EOI flag and bail out
120
121 @L4:    ldx     tmp2            ; Get the handle
122         lda     #LFN_EOF
123         ora     fdtab,x
124         sta     fdtab,x
125
126 ; Read done, close the input channel
127
128 done:   jsr     CLRCH
129
130 ; Clear _oserror and return the number of chars read
131
132 eof:    lda     #0
133         sta     __oserror
134         lda     ptr3
135         ldx     ptr3+1
136         rts
137
138 ; Error entry: Device not present
139
140 devnotpresent:
141         lda     #ENODEV
142         jmp     __directerrno   ; Sets _errno, clears _oserror, returns -1
143
144 ; Error entry: The given file descriptor is not valid or not open
145
146 invalidfd:
147         lda     #EBADF
148         jmp     __directerrno   ; Sets _errno, clears _oserror, returns -1
149
150 .endproc
151
152
153 ;--------------------------------------------------------------------------
154
155 .bss
156
157 unit:   .res    1
158
159