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