X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=libsrc%2Fatari%2Fread.s;h=acb415efd319330642a1ec87f8024f679fae5bfc;hb=00fca46d2a0a16d463886d0de4d30bf428a0aba1;hp=ef16ae8cef34c9d0907ca4410a08879fbadacc1e;hpb=1c29bd366352e59e78aa1084751ddefeb8ca5326;p=cc65 diff --git a/libsrc/atari/read.s b/libsrc/atari/read.s index ef16ae8ce..acb415efd 100644 --- a/libsrc/atari/read.s +++ b/libsrc/atari/read.s @@ -1,33 +1,182 @@ ; -; Christian Groessler, Apr-2000 +; 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 - 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 - lda #0 - sta __oserror ; clear system dependend error code - pla ; get buf len lo - rts + .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 + jmp __inviocb + + +.ifdef LINEBUF + +; line oriented input + + .segment "EXTZP" : 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 + + .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 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 +