]> git.sur5r.net Git - cc65/blobdiff - libsrc/atari/lseek.s
The spans do now contain the size of a span, no longer the end offset.
[cc65] / libsrc / atari / lseek.s
index f9609f2ab7ab137813f33ea4a619981da20c9032..244095969f26d6a571396d99cb6c5297112e1d49 100644 (file)
@@ -1,5 +1,5 @@
 ;
-; Christian Groessler, August 2000
+; Christian Groessler, May 2002
 ;
 ; this file provides the lseek() function
 ;
 
 
        .export         _lseek
-       .import         incsp6,__errno,__oserror
-       .importzp       sreg
+       .import         incsp6,__oserror
+       .import         __inviocb,ldax0sp,ldaxysp,fdtoiocb
+       .import         __dos_type
+       .import         fd_table
+       .importzp       sreg,ptr1,ptr2,ptr3,ptr4
+       .importzp       tmp1,tmp2,tmp3
        .include        "atari.inc"
-       .include        "../common/errno.inc"
+       .include        "errno.inc"
+       .include        "fd.inc"
+
+; seeking not supported, return -1 and ENOSYS errno value
+no_supp:jsr    incsp6
+       lda     #<ENOSYS
+       jsr     __directerrno   ; returns with $FFFF in AX
+       sta     sreg
+       sta     sreg+1
+       rts
+
+parmerr:
+iocberr:jsr    incsp6
+       ldx     #255
+       stx     sreg
+       stx     sreg+1
+       jmp     __inviocb
+
+
+; lseek() entry point
 
 .proc  _lseek
 
-; dummy implementation, return -1 and ENOSYS errno value
-       jsr     incsp6
-       lda     #<ENOSYS
-       sta     __errno
-       lda     #>ENOSYS
-       sta     __errno
-       ldx     #0
-       stx     __oserror
+       cpx     #0              ; sanity check whence parameter
+       bne     parmerr
+       cmp     #3              ; valid values are 0..2
+       bcs     parmerr
+       sta     tmp1            ; remember whence
+
+       ldy     #5
+       jsr     ldaxysp         ; get fd
+       jsr     fdtoiocb        ; convert to iocb in A, fd_table index in X
+       bmi     iocberr
+       sta     tmp3            ; remember iocb
+
+       jsr     chk_supp        ; check, whether seeking is supported by DOS/Disk
+       bcc     no_supp
+
+       ldx     tmp1            ; whence
+       beq     cur
        dex
-       txa
+       beq     end
+
+; SEEK_SET
+       dex
+       stx     ptr3
+       stx     ptr3+1
+       stx     ptr4
+       stx     ptr4+1
+       beq     cont
+
+; SEEK_CUR
+cur:   ldx     tmp3
+       lda     #38             ; NOTE
+       sta     ICCOM,x
+       jsr     CIOV            ; read it
+       bmi     xxerr
+l01:   lda     ICAX3,x         ; low byte of position
+       sta     ptr3
+       lda     ICAX4,x         ; med byte of position
+       sta     ptr3+1
+       lda     ICAX5,x         ; high byte of position
+       sta     ptr4
+       lda     #0
+       sta     ptr4+1
+       beq     cont
+
+; SEEK_END
+end:   ldx     tmp3
+       lda     #39             ; get file size
+       sta     ICCOM,x
+       jsr     CIOV
+       bpl     l01
+
+; error returned from CIO
+xxerr: tya
+       pha
+       jsr     incsp6
+       pla
+       jsr     __mappederrno   ; returns with $FFFF in AX
        sta     sreg
        sta     sreg+1
        rts
 
+; check for offset 0, SEEK_CUR (get current position)
+cont:  ldy     #3
+       jsr     ldaxysp         ; get upper word
+       sta     ptr1
+       stx     ptr1+1
+       jsr     ldax0sp         ; get lower word
+       stx     tmp2
+       ora     tmp2
+       ora     ptr1
+       ora     ptr1+1
+       bne     seek
+       lda     tmp1            ; whence (0 = SEEK_CUR)
+       bne     seek
+
+; offset 0, SEEK_CUR: return current fp
+ret:   jsr     incsp6
+
+       lda     ptr4+1
+       sta     sreg+1
+       lda     ptr4
+       sta     sreg
+       ldx     ptr3+1
+       lda     ptr3
+
+.if 0
+       ; return exactly the position DOS has
+       ldx     tmp3
+       lda     #38             ; NOTE
+       sta     ICCOM,x
+       jsr     CIOV            ; read it
+       bmi     xxerr
+       lda     #0
+       sta     sreg+1
+       lda     ICAX5,x         ; high byte of position
+       sta     sreg
+       lda     ICAX3,x         ; low byte of position
+       pha
+       lda     ICAX4,x         ; med byte of position
+       tax
+       pla
+.endif
+
+       rts
+
+parmerr1: jmp  parmerr
+
+; we have to call POINT
+seek:  jsr     ldax0sp         ; get lower word of new offset
+       clc
+       adc     ptr3
+       sta     ptr3
+       txa
+       adc     ptr3+1
+       sta     ptr3+1
+       lda     ptr1
+       adc     ptr4
+       sta     ptr4
+       lda     ptr1+1
+       adc     ptr4+1
+       sta     ptr4+1
+       bne     parmerr1        ; resulting value too large
+
+       ldx     tmp3            ; IOCB
+       lda     ptr3
+       sta     ICAX3,x
+       lda     ptr3+1
+       sta     ICAX4,x
+       lda     ptr4
+       sta     ICAX5,x
+       lda     #37             ;POINT
+       sta     ICCOM,x
+       jsr     CIOV
+       bpl     ret
+       bmi     xxerr
+
 .endproc
+
+; check, whether seeking is supported
+; tmp3:                iocb
+; X:           index into fd_table
+;
+; On non-SpartaDOS, seeking is not supported.
+; We check, whether CIO function 39 (get file size) returns OK.
+; If yes, NOTE and POINT work with real file offset.
+; If not, NOTE and POINT work with the standard ScNum/Offset values.
+; We remember a successful check in fd_table.ft_flag, bit 3.
+
+chk_supp:
+       lda     fd_table+ft_flag,x
+       and     #8
+       bne     supp
+
+; do the test
+       lda     __dos_type
+       cmp     #SPARTADOS
+       bne     ns1
+       txa
+       pha
+       lda     DOS+1           ; get SpartaDOS version
+       cmp     #$40
+       bcs     supp1           ; SD-X (ver 4.xx) supports seeking on all disks
+       ldx     tmp3            ; iocb to use
+       lda     #39             ; get file size
+       sta     ICCOM,x
+       jsr     CIOV
+       bmi     notsupp         ; error code ? should be 168 (invalid command)
+
+; seeking is supported on this DOS/Disk combination
+
+supp1: pla
+       tax
+       lda     #8
+       ora     fd_table+ft_flag,x
+       sta     fd_table+ft_flag,x
+supp:  sec
+       rts
+
+notsupp:pla
+ns1:   clc
+       rts
+