diff --git a/libsrc/atari/read.s b/libsrc/atari/read.s index ef16ae8ce..b5b6ee011 100644 --- a/libsrc/atari/read.s +++ b/libsrc/atari/read.s @@ -1,5 +1,5 @@ ; -; Christian Groessler, Apr-2000 +; Christian Groessler, May-2004 ; ; 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 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 @@ -24,10 +32,151 @@ done: lda ICBLL,x ; buf len lo pha ; save lda ICBLH,x ; get buf len hi tax ; to X - lda #0 +okdone: lda #0 sta __oserror ; clear system dependend error code pla ; get buf len lo rts _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 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 +