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