mirror of
https://github.com/cc65/cc65.git
synced 2024-07-22 12:29:06 +00:00
implement line buffered reads, optional with LINEBUF define
git-svn-id: svn://svn.cc65.org/cc65/trunk@3052 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
ef6a034153
commit
0b658d7319
@ -1,5 +1,5 @@
|
|||||||
;
|
;
|
||||||
; Christian Groessler, Apr-2000
|
; Christian Groessler, May-2004
|
||||||
;
|
;
|
||||||
; int __fastcall__ read(int fd,void *buf,int count)
|
; int __fastcall__ read(int fd,void *buf,int count)
|
||||||
;
|
;
|
||||||
@ -12,6 +12,14 @@ _read: jsr __rwsetup ; do common setup for read and write
|
|||||||
beq done ; if size 0, it's a no-op
|
beq done ; if size 0, it's a no-op
|
||||||
cpx #$FF ; invalid iocb?
|
cpx #$FF ; invalid iocb?
|
||||||
beq _inviocb
|
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
|
lda #GETCHR ; iocb command code
|
||||||
sta ICCOM,x
|
sta ICCOM,x
|
||||||
jsr CIOV ; read it
|
jsr CIOV ; read it
|
||||||
@ -24,10 +32,151 @@ done: lda ICBLL,x ; buf len lo
|
|||||||
pha ; save
|
pha ; save
|
||||||
lda ICBLH,x ; get buf len hi
|
lda ICBLH,x ; get buf len hi
|
||||||
tax ; to X
|
tax ; to X
|
||||||
lda #0
|
okdone: lda #0
|
||||||
sta __oserror ; clear system dependend error code
|
sta __oserror ; clear system dependend error code
|
||||||
pla ; get buf len lo
|
pla ; get buf len lo
|
||||||
rts
|
rts
|
||||||
|
|
||||||
_inviocb:
|
_inviocb:
|
||||||
jmp __inviocb
|
jmp __inviocb
|
||||||
|
|
||||||
|
|
||||||
|
.ifdef LINEBUF
|
||||||
|
|
||||||
|
; line oriented input
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
; 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
|
||||||
|
|
||||||
|
; return bytes from line buffer
|
||||||
|
; use buflen and index to access buffer
|
||||||
|
; update index
|
||||||
|
; use dataptr as a temporary pointer
|
||||||
|
|
||||||
|
use_buf:
|
||||||
|
lda buflen
|
||||||
|
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
|
||||||
|
bne icbll_copy
|
||||||
|
|
||||||
|
; brk ; not reached
|
||||||
|
|
||||||
|
.zeropage
|
||||||
|
|
||||||
|
index: .res 1 ; index into line buffer
|
||||||
|
buflen: .res 1 ; length of used part of buffer
|
||||||
|
cbs: .res 1 ; current buffer size: buflen - index
|
||||||
|
dataptr:.res 2 ; temp pointer to user buffer
|
||||||
|
copylen:.res 1 ; temp counter
|
||||||
|
|
||||||
|
.bss
|
||||||
|
|
||||||
|
linebuf:.res LINEBUF ; the line buffer
|
||||||
|
|
||||||
|
.endif ; .ifdef LINEBUF
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user