]> git.sur5r.net Git - cc65/blob - libsrc/atari/lseek.s
Atari: add support for BW-DOS. Initially contributed by Daniel Serpell.
[cc65] / libsrc / atari / lseek.s
1 ;
2 ; Christian Groessler, May 2002
3 ;
4 ; this file provides the lseek() function
5 ;
6 ; off_t __fastcall__ lseek(int fd, off_t offset, int whence);
7 ;
8
9
10         .export         _lseek
11         .import         incsp6,__oserror
12         .import         __inviocb,ldax0sp,ldaxysp,fdtoiocb
13         .import         __dos_type
14         .import         fd_table
15         .importzp       sreg,ptr1,ptr2,ptr3,ptr4
16         .importzp       tmp1,tmp2,tmp3
17         .include        "atari.inc"
18         .include        "errno.inc"
19         .include        "fd.inc"
20
21 ; seeking not supported, return -1 and ENOSYS errno value
22 no_supp:jsr     incsp6
23         lda     #<ENOSYS
24         jsr     __directerrno   ; returns with $FFFF in AX
25         sta     sreg
26         sta     sreg+1
27         rts
28
29 parmerr:
30 iocberr:jsr     incsp6
31         ldx     #255
32         stx     sreg
33         stx     sreg+1
34         jmp     __inviocb
35
36
37 ; lseek() entry point
38
39 .proc   _lseek
40
41         cpx     #0              ; sanity check whence parameter
42         bne     parmerr
43         cmp     #3              ; valid values are 0..2
44         bcs     parmerr
45         sta     tmp1            ; remember whence
46
47         ldy     #5
48         jsr     ldaxysp         ; get fd
49         jsr     fdtoiocb        ; convert to iocb in A, fd_table index in X
50         bmi     iocberr
51         sta     tmp3            ; remember iocb
52
53         jsr     chk_supp        ; check, whether seeking is supported by DOS/Disk
54         bcc     no_supp
55
56         ldx     tmp1            ; whence
57         beq     cur
58         dex
59         beq     end
60
61 ; SEEK_SET
62         dex
63         stx     ptr3
64         stx     ptr3+1
65         stx     ptr4
66         stx     ptr4+1
67         beq     cont
68
69 ; SEEK_CUR
70 cur:    ldx     tmp3
71         lda     #NOTE
72         sta     ICCOM,x
73         jsr     CIOV            ; read it
74         bmi     xxerr
75 l01:    lda     ICAX3,x         ; low byte of position
76         sta     ptr3
77         lda     ICAX4,x         ; med byte of position
78         sta     ptr3+1
79         lda     ICAX5,x         ; high byte of position
80         sta     ptr4
81         lda     #0
82         sta     ptr4+1
83         beq     cont
84
85 ; SEEK_END
86 end:    ldx     tmp3
87         lda     #GETFL
88         sta     ICCOM,x
89         jsr     CIOV
90         bpl     l01
91
92 ; error returned from CIO
93 xxerr:  tya
94         pha
95         jsr     incsp6
96         pla
97         jsr     __mappederrno   ; returns with $FFFF in AX
98         sta     sreg
99         sta     sreg+1
100         rts
101
102 ; check for offset 0, SEEK_CUR (get current position)
103 cont:   ldy     #3
104         jsr     ldaxysp         ; get upper word
105         sta     ptr1
106         stx     ptr1+1
107         jsr     ldax0sp         ; get lower word
108         stx     tmp2
109         ora     tmp2
110         ora     ptr1
111         ora     ptr1+1
112         bne     seek
113         lda     tmp1            ; whence (0 = SEEK_CUR)
114         bne     seek
115
116 ; offset 0, SEEK_CUR: return current fp
117 ret:    jsr     incsp6
118
119         lda     ptr4+1
120         sta     sreg+1
121         lda     ptr4
122         sta     sreg
123         ldx     ptr3+1
124         lda     ptr3
125
126 .if 0
127         ; return exactly the position DOS has
128         ldx     tmp3
129         lda     #NOTE
130         sta     ICCOM,x
131         jsr     CIOV            ; read it
132         bmi     xxerr
133         lda     #0
134         sta     sreg+1
135         lda     ICAX5,x         ; high byte of position
136         sta     sreg
137         lda     ICAX3,x         ; low byte of position
138         pha
139         lda     ICAX4,x         ; med byte of position
140         tax
141         pla
142 .endif
143
144         rts
145
146 parmerr1: jmp   parmerr
147
148 ; we have to call POINT
149 seek:   jsr     ldax0sp         ; get lower word of new offset
150         clc
151         adc     ptr3
152         sta     ptr3
153         txa
154         adc     ptr3+1
155         sta     ptr3+1
156         lda     ptr1
157         adc     ptr4
158         sta     ptr4
159         lda     ptr1+1
160         adc     ptr4+1
161         sta     ptr4+1
162         bne     parmerr1        ; resulting value too large
163
164         ldx     tmp3            ; IOCB
165         lda     ptr3
166         sta     ICAX3,x
167         lda     ptr3+1
168         sta     ICAX4,x
169         lda     ptr4
170         sta     ICAX5,x
171         lda     #POINT
172         sta     ICCOM,x
173         jsr     CIOV
174         bpl     ret
175         bmi     xxerr
176
177 .endproc
178
179 ; check whether seeking is supported
180 ; tmp3:         iocb
181 ; X:            index into fd_table
182 ;
183 ; On non-SpartaDOS, seeking is not supported.
184 ; We check, whether CIO function 39 (get file size) returns OK.
185 ; If yes, NOTE and POINT work with real file offset.
186 ; If not, NOTE and POINT work with the standard ScNum/Offset values.
187 ; We remember a successful check in fd_table.ft_flag, bit 3.
188
189 chk_supp:
190         lda     fd_table+ft_flag,x
191         and     #8
192         bne     supp
193
194 ; do the test
195         lda     __dos_type
196         cmp     #SPARTADOS
197         beq     :+
198         cmp     #BWDOS
199         beq     :+
200         cmp     #REALDOS
201         bne     ns1
202 :       txa
203         pha
204         lda     DOS+1           ; get SpartaDOS version
205         cmp     #$40
206         bcs     supp1           ; SD-X (ver 4.xx) supports seeking on all disks
207         ldx     tmp3            ; iocb to use
208         lda     #GETFL
209         sta     ICCOM,x
210         jsr     CIOV
211         bmi     notsupp         ; error code ? should be 168 (invalid command)
212
213 ; seeking is supported on this DOS/Disk combination
214
215 supp1:  pla
216         tax
217         lda     #8
218         ora     fd_table+ft_flag,x
219         sta     fd_table+ft_flag,x
220 supp:   sec
221         rts
222
223 notsupp:pla
224 ns1:    clc
225         rts
226