File: read.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (182 lines) | stat: -rw-r--r-- 4,635 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
;
; Christian Groessler, Jul-2005
;
; int __fastcall__ read(int fd,void *buf,int count)
;

        .include "atari.inc"
        .import __rwsetup,__do_oserror,__inviocb,__oserror
        .export _read

_read:  jsr     __rwsetup       ; do common setup for read and write
        beq     done            ; if size 0, it's a no-op
        cpx     #$FF            ; invalid iocb?
        beq     _inviocb

.ifdef  LINEBUF
        ; E: should be always at IOCB #0
        ; fixme: what happens when user closes and reopens stdin?
        cpx     #0              ; E: handler (line oriented keyboard input)?
        beq     do_line
.endif

        lda     #GETCHR         ; iocb command code
        sta     ICCOM,x
        jsr     CIOV            ; read it
        bpl     done
        cpy     #EOFERR         ; eof is treated specially
        beq     done
        jmp     __do_oserror    ; update errno

done:   lda     ICBLL,x         ; buf len lo
        pha                     ; save
        lda     ICBLH,x         ; get buf len hi
        tax                     ; to X
okdone: lda     #0
        sta     __oserror       ; clear system dependend error code
        pla                     ; get buf len lo
        rts

_inviocb:
        jmp     __inviocb


.ifdef  LINEBUF

; line oriented input

        .segment        "EXTZP" : zeropage

index:  .res    1               ; index into line buffer
cbs:    .res    1               ; current buffer size: buflen - index
dataptr:.res    2               ; temp pointer to user buffer
copylen:.res    1               ; temp counter

        .bss

buflen: .res    1               ; length of used part of buffer
linebuf:.res    LINEBUF         ; the line buffer

        .code

do_line:
        lda     buflen          ; line buffer active?
        bne     use_buf         ; yes, get data from there

        ; save user buffer address & length
        ; update IOCB to point to line buffer
        lda     ICBLL,x
        pha
        lda     #LINEBUF
        sta     ICBLL,x
        ;--------
        lda     ICBLH,x
        pha
        lda     #0
        sta     ICBLH,x
        ;--------
        lda     ICBAL,x
        pha
        lda     #<linebuf
        sta     ICBAL,x
        ;--------
        lda     ICBAH,x
        pha
        lda     #>linebuf
        sta     ICBAH,x

        lda     #GETREC
        sta     ICCOM,x
        jsr     CIOV            ; read input data
        bpl     newbuf
        cpy     #EOFERR         ; eof is treated specially
        beq     newbuf
        pla                     ; fix stack
        pla
        pla
        pla
        jmp     __do_oserror    ; update errno

newbuf:
        lda     ICBLL,x         ; get # of bytes read
        sta     buflen
        lda     #0
        sta     index           ; fresh buffer

        ; restore user buffer address & length
        pla
        sta     ICBAH,x
        ;--------
        pla
        sta     ICBAL,x
        ;--------
        pla
        sta     ICBLH,x
        ;--------
        pla
        sta     ICBLL,x

        ; fall into use_buf
        lda     buflen

; return bytes from line buffer
; use buflen and index to access buffer
; update index
; use dataptr as a temporary pointer

use_buf:
        sec
        sbc     index           ; size of unread data in the buffer
        sta     cbs

        lda     ICBLL,x         ; buf len lo
        cmp     cbs             ; larger than buffer size?
        beq     bl1
        bcs     btsmall         ; yes, adjust length

bl1:    lda     ICBLH,x         ; get buf len hi
        bne     btsmall         ; buffer too small: buffer contents < read size

; copy ICBLL,x bytes

icbll_copy:

        lda     ICBAL,x         ; buffer address
        sta     dataptr
        lda     ICBAH,x         ; buffer address
        sta     dataptr+1
        lda     ICBLL,x
        sta     copylen
        pha                     ; remember for return value
        ldy     #0
        ldx     index

copy:   lda     linebuf,x
        sta     (dataptr),y
        iny
        inx
        dec     copylen
        bne     copy

        pla                     ; length
        pha                     ; save length to return at okdone

        clc
        adc     index
        sta     index
        cmp     buflen          ; buffer used up?
        bcc     c1              ; not yet

        lda     #0
        sta     buflen          ; indicate empty line buffer

c1:     ldx     #0
        jmp     okdone          ; return to caller

btsmall:
        lda     cbs
        sta     ICBLL,x
        bpl     icbll_copy

.endif          ; .ifdef LINEBUF