]> git.sur5r.net Git - cc65/commitdiff
implement line buffered reads, optional with LINEBUF define
authorcpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 28 May 2004 22:01:14 +0000 (22:01 +0000)
committercpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 28 May 2004 22:01:14 +0000 (22:01 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3052 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/atari/read.s

index ef16ae8cef34c9d0907ca4410a08879fbadacc1e..b5b6ee0111fcce80a2f8bfff9b30b5dd23a6559c 100644 (file)
@@ -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     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
+