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