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
|