]> git.sur5r.net Git - cc65/commitdiff
implementation which supports SpartaDOS format disks on SpartaDOS
authorcpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 23 May 2002 21:29:55 +0000 (21:29 +0000)
committercpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 23 May 2002 21:29:55 +0000 (21:29 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1284 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/atari/lseek.s

index 27bc1ad657e61a4118623a6976663b5dc886f663..259d89ab29bcde2e5011cd118c617d7eafaea35d 100644 (file)
@@ -1,5 +1,5 @@
 ;
-; Christian Groessler, August 2000
+; Christian Groessler, May 2002
 ;
 ; this file provides the lseek() function
 ;
@@ -8,19 +8,21 @@
 
 
        .export         _lseek
-       .import         incsp6,__errno,__oserror
-       .importzp       sreg
+       .import         incsp6,__oserror
+       .import         __inviocb,ldax0sp,ldaxysp,fdtoiocb
+       .import         __seterrno
+       .import         fd_table
+       .importzp       sreg,ptr1,ptr2,ptr3,ptr4
+       .importzp       tmp1,tmp2,tmp3
        .include        "atari.inc"
        .include        "errno.inc"
+       .include        "fd.inc"
 
-.proc  _lseek
-
-; dummy implementation, return -1 and ENOSYS errno value
-       jsr     incsp6
+; seeking not supported, return -1 and ENOSYS errno value
+no_supp:jsr    incsp6
        lda     #<ENOSYS
-       sta     __errno
-       lda     #>ENOSYS
-       sta     __errno+1
+       ldx     #>ENOSYS
+       jsr     __seterrno
        ldx     #0
        stx     __oserror
        dex
        sta     sreg+1
        rts
 
+parmerr:
+iocberr:jsr    incsp6
+       ldx     #255
+       stx     sreg
+       stx     sreg+1
+       jmp     __inviocb
+
+
+; lseek() entry point
+
+.proc  _lseek
+
+       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
+       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: sty     __oserror
+       bmi     iocberr
+
+; 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
+;
+; We check, whether CIO function 39 (get file size) returns OK.
+; If yes, NOTE and POINT work with real file offset. @@@ check out more DOS versions @@@
+; 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
+unkn:  txa
+       pha
+       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
+
+       pla
+       tax
+       lda     #8
+       ora     fd_table+ft_flag,x
+       sta     fd_table+ft_flag,x
+supp:  sec
+       rts
+
+notsupp:pla
+       clc
+       rts
+