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