Subversion Repositories Spectranet

[/] [branches/] [gnubinutils/] [rom/] [vfs.asm] - Blame information for rev 384

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 211 winston
;The MIT License
2
;
3
;Copyright (c) 2009 Dylan Smith
4
;
5
;Permission is hereby granted, free of charge, to any person obtaining a copy
6
;of this software and associated documentation files (the "Software"), to deal
7
;in the Software without restriction, including without limitation the rights
8
;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
;copies of the Software, and to permit persons to whom the Software is
10
;furnished to do so, subject to the following conditions:
11
;
12
;The above copyright notice and this permission notice shall be included in
13
;all copies or substantial portions of the Software.
14
;
15
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
;THE SOFTWARE.
22
 
23
;----------------------------------------------------------------------------
24
; VFS routines.
25
; These routines find the appropriate jump table for filesystems and file
26
; descriptors for standard routines.
27
 
28
; A ROM module that looks after a filesystem should have a vector table
29
; immediately after the general vector table, at address 0x2010.
30
; There are actually two vector tables - one that defines the call address
31
; of routines that act on open file descriptors (eg read, write, close etc.)
32
; and another tables that don't (mount, open, umount etc), and a table that
33
; lists calls that work on directory descriptors (readdir, closedir)
34
;
35
; The tables look like this:
36
; FS level operations
37
; 0x2013:       UMOUNT
38
; 0x2016:       OPENDIR
39
; 0x2019:       OPEN
40
; 0x201C:       UNLINK (delete a file)
41
; 0x201F:       MKDIR
42
; 0x2022:       RMDIR
43
; 0x2025:       SIZE (routine to get the size of the filesystem)
44
; 0x2028:       FREE (free space remaining)
45
; 0x202B:       STAT (stat a file)
46
; 0x202E:       CHMOD (change file mode)
47
; File descriptor level operations
48
; 0x2031:       READ
49
; 0x2034:       WRITE
50
; 0x2037:       LSEEK
51
; 0x203A:       CLOSE
52
; 0x203D:       POLL
53
; Directory descriptor level operations
54
; 0x2040:       READDIR
55
; 0x2043:       CLOSEDIR
56
;
57
; For functions that are not implemented, an address to a short routine
58
; that sets the carry flag and makes A the appropriate return code should
59
; be provided.
60 384 winston
.include        "moduledefs.inc"
61
.include        "sysvars.inc"
62
.include        "sysdefs.inc"
63
.include        "sockdefs.inc"
64
 
65 211 winston
;----------------------------------------------------------------------------
66
; Dispatcher routines.
67 384 winston
.globl F_fd_dispatch
68
F_fd_dispatch:
69 211 winston
        ex (sp), hl             ; fetch return address, saving HL
70
        push de
71 213 winston
        ld d, 0x3F              ; point DE at memory address containing
72
        ld e, a                 ; the fd's flags
73
        ex de, hl
74
        bit CLOSEDBIT, (hl)
75
        ex de, hl
76 214 winston
        jr nz, J_notopen
77 211 winston
        ld de, FDVECBASE        ; set base address of the descriptor table
78
        jr F_dispatch
79 384 winston
J_notopen:
80 213 winston
        pop de
81 218 winston
        pop hl
82 384 winston
        ld a, 0x06              ; TODO: errno.asm1 - EBADF
83 213 winston
        scf
84
        ret
85 211 winston
 
86 384 winston
.globl F_vfs_dispatch
87
F_vfs_dispatch:
88 251 winston
        call F_cleanpath        ; remove leading/trailing space
89 230 winston
        call F_resolvemp        ; See if a mount point is specified
90 211 winston
        ex (sp), hl
91
        push de
92 218 winston
        push af
93 211 winston
        ld de, VFSVECBASE
94 218 winston
        add a, e                ; find the address of the VFS vector
95
        ld e, a                 ; and check that something is mounted
96
        ld a, (de)
97
        and a                   ; not mounted if the VFS ROM no. was 0
98
        jr nz, F_dispatch_3
99 384 winston
.notmounted2:
100 218 winston
        pop af                  ; fix the stack
101
        pop de
102
        pop hl
103 384 winston
        ld a, 0x23              ; TODO: errno.asm2
104 218 winston
        scf
105
        ret
106 211 winston
 
107 384 winston
.globl F_dir_dispatch
108
F_dir_dispatch:
109 211 winston
        ex (sp), hl
110
        push de
111 214 winston
        ld d, 0x3F              ; point DE at the address containing
112
        ld e, a                 ; directory handle information
113
        ex af, af'
114
        ld a, (de)
115
        and a                   ; is this a valid open descriptor?
116
        jr z, J_notopen
117
        ex af, af'
118
        push af
119
        jr F_dispatch_2
120 211 winston
 
121
;--------------------------------------------------------------------------
122
; F_dispatch
123
; Find the appropriate ROM page for the file (or whatever) descriptor,
124
; and fetch the jump address from the jump table within.
125 384 winston
.globl F_dispatch_notfd
126
F_dispatch_notfd:
127 212 winston
        push af
128
        jr F_dispatch_1
129 384 winston
.globl F_dispatch
130
F_dispatch:
131 211 winston
        push af
132
        sub FDBASE%256
133 384 winston
.globl F_dispatch_1
134
F_dispatch_1:
135 211 winston
        add a, e                ; Calculate the address in the fd table
136 384 winston
.globl F_dispatch_2
137
F_dispatch_2:
138 211 winston
        ld e, a                 ; make DE point to it
139
        ld a, (de)              ; get the ROM to page
140
        and a                   ; ROM 0 is handled specially
141 218 winston
        jr z, isasocket
142 384 winston
.globl F_dispatch_3
143
F_dispatch_3:
144 214 winston
        ex af, af'              ; save AF while copying the current page
145 211 winston
        ld a, (v_pgb)           ; save current page
146
        ld (v_vfspgb_vecsave), a
147
        ex af, af'
148
        call F_setpageB         ; page the ROM
149
 
150
        ld a, l                 ; calculate the table offset for the function
151
        sub VFSJUMPOFFSET
152
        ld (VFSJUMP+1), a       ; set the jump vector
153
        pop af                  ; restore registers
154
        pop de
155
        pop hl
156
        call VFSJUMP
157
 
158
        push af                 ; restore original page B
159
        ld a, (v_vfspgb_vecsave)
160
        call F_setpageB
161
        pop af
162
        ret
163
 
164
; If someone access a socket via read/write rather than send/recv
165
; it's handled here. There are only four functions that can be done to
166
; a socket via the VFS interface.
167 384 winston
isasocket:
168 211 winston
        ld a, 0xCC              ; Check for READ. Note the LSB addresses
169
        cp l                    ; are +3 on the actual (because CALL put
170 384 winston
        jr z, .sockread8                ; the return address, not the actual
171 211 winston
        ld a, 0xCF              ; address on the stack!)
172
        cp l
173 384 winston
        jr z, .sockwrite8
174 211 winston
        ld a, 0xD8              ; POLL
175
        cp l
176 384 winston
        jr z, .sockpoll8
177 211 winston
        ld a, 0xD5              ; CLOSE
178 384 winston
        jr nz, .badcall8
179 211 winston
        pop af
180
        pop de
181
        pop hl
182
        jp F_sockclose
183 384 winston
.sockread8:
184 211 winston
        pop af
185
        pop de
186
        pop hl
187
        jp F_recv
188 384 winston
.sockwrite8:
189 211 winston
        pop af
190
        pop de
191
        pop hl
192
        jp F_send
193 384 winston
.sockpoll8:
194 211 winston
        pop af
195
        pop de
196
        pop hl
197
        jp F_pollfd
198 384 winston
.badcall8:
199 211 winston
        pop af
200
        pop de
201
        pop hl
202
        ld a, 0xFF              ; TODO: proper return code
203
        scf
204
        ret
205
 
206
;---------------------------------------------------------------------------
207
; F_mount
208
; Searches for an appropriate mount routines in the ROM modules we have,
209
; then tries to mount the FS.
210
; Parameters:           IX - pointer to an 10 byte structure that contains:
211
;                       byte 0,1 - pointer to null terminated protocol
212
;                       byte 2,3 - pointer to null terminated hostname
213
;                       byte 4,5 - pointer to null terminated mount source
214
;                       byte 6,7 - pointer to null terminated user id
215
;                       byte 8,9 - pointer to null terminated passwd
216
;                       A - device number
217
; The actual mount routine that gets called should do the following:
218
; - If the protocol is supported, mount the FS and return with Z and C reset
219
; - If the proto is supported, but the FS can't be mounted, return with C set
220
; - If the proto is not recognised, return with Z set
221 384 winston
.globl F_mount
222
F_mount:
223 211 winston
        ; First search for a ROM that handles this protocol.
224
        ld (v_mountnumber), a   ; save device number
225
        ld hl, vectors
226 384 winston
.findrom9:
227 211 winston
        ld a, (hl)              ; get ROM ID
228
        and a                   ; check for the terminator
229 384 winston
        jr z, .notfound9                ; no ROM found that handles this protocol
230
.testproto9:
231 211 winston
        push hl                 ; save current vector table address
232
        ld a, l
233
        sub ROMVECOFFS          ; subtract the base addr to get the ROM slot
234
        push af                 ; save ROM slot number
235
        call F_pushpageB
236
        ld hl, (MOD_VEC_MOUNT)  ; get address of the real mount routine
237 214 winston
        ld a, h                 ; H must be 0x20-0x2F for a valid MOUNT routine
238
        and 0xF0                ; mask out low nibble
239
        cp 0x20                 ; result should be 0x20 for valid MOUNT
240 384 winston
        jr nz, .testnext9
241
        ld de, .return9         ; simulate CALL instruction with JP (HL)
242 211 winston
        push de
243 234 winston
        ld a, (v_mountnumber)
244 211 winston
        jp (hl)
245 384 winston
.return9:
246
        jr c, .mountfailed9     ; Tried but failed to mount?
247
        jr z, .testnext9                ; Protocol is not ours?
248 211 winston
        call F_poppageB         ; restore original page B
249
        ld a, (v_mountnumber)   ; get device number
250 384 winston
        add a, VFSVECBASE%256   ; and calculate the address in sysvars
251 211 winston
        ld h, 0x3F              ; MSB of the sysvars area
252
        ld l, a                 ; LSB - HL now has the addr of the fs table
253
        pop af                  ; restore ROM page number
254
        ld (hl), a              ; Put the ROM number in the filesystem table
255
        pop hl                  ; restore the stack
256
        ret
257 384 winston
.testnext9:
258 211 winston
        call F_poppageB         ; restore stack
259
        pop af                  ; ROM slot number
260
        pop hl                  ; table pointer
261
        inc l                   ; and point it to the next ROM list entry
262 384 winston
        jr .findrom9
263 211 winston
 
264 384 winston
.mountfailed9:
265 319 winston
        ex af, af'
266 211 winston
        call F_poppageB         ; restore stack and page
267 319 winston
        pop af                  ; unwind stack
268 211 winston
        pop hl                  ; restore HL
269 319 winston
        ex af, af'
270 211 winston
        ret
271 384 winston
.notfound9:
272 211 winston
        ld a, 0xFE              ; TODO: proper return code here
273
        scf
274
        ret
275 236 winston
 
276
;--------------------------------------------------------------------------
277
; F_freemountpoint
278
; Frees a mount point, passed in A
279 384 winston
.globl F_freemountpoint
280
F_freemountpoint:
281
        add a, VFSVECBASE % 256 ; calculate the address in sysvars
282 236 winston
        ld h, 0x3F              ; sysvars page
283
        ld l, a
284
        ld (hl), 0              ; clear it down
285
        ret
286 238 winston
 
287
;--------------------------------------------------------------------------
288
; F_setmountpoint
289
; Sets the default mountpoint in use, passed in A
290 384 winston
.globl F_setmountpoint
291
F_setmountpoint:
292 238 winston
        cp 4                    ; mount point must be <= 3
293
        ccf                     ; flip the carry flag
294
        ret c                   ; so if there's an error we return with C
295
        ld (v_vfs_curmount), a
296
        ret
297 285 winston
 
298 211 winston
;--------------------------------------------------------------------------
299 285 winston
; F_resalloc
300
; Resource allocator/deallocator for file and directory descriptors.
301
; Parameters: FD param in A
302
;             Flags in C
303
; C bit 0 = Set=Allocate, reset=free
304
; C bit 1 = Set=Directory, reset=File
305 384 winston
.globl F_resalloc
306
F_resalloc:
307 285 winston
        bit 1, c
308
        jr nz, F_allocdirhnd
309
;--------------------------------------------------------------------------
310 211 winston
; F_allocfd
311
; Allocates a file descriptor.
312
; Parameters:   A = ROM number for the fd
313
; On return HL = address of fd. Functions that use this should set this
314
; to a value that means something (and bit 7 must be reset). L = actual
315
; fd number.
316 384 winston
.globl F_allocfd
317
F_allocfd:
318 285 winston
        bit 0, c
319
        jr z, F_freefd
320 211 winston
        push bc
321
        ld hl, v_fd1hwsock      ; lowest address in fd table
322
        ld b, MAX_FDS
323 384 winston
.findloop13:
324 211 winston
        bit 7, (hl)             ; not allocated yet?
325 384 winston
        jr nz, .alloc13
326 211 winston
        inc l
327 384 winston
        djnz .findloop13                ; keep looking until none left
328 211 winston
        scf                     ; out of free file descriptors
329
        pop bc
330
        ret
331 384 winston
.alloc13:
332 213 winston
        res 7, (hl)             ; basic allocation
333
        push hl                 ; save FD address and FD number
334 211 winston
        ld b, a                 ; save parameter
335
        ld a, l
336 384 winston
        add a, VECOFFS          ; find the address of the vector table
337 211 winston
        ld l, a                 ; and make HL point to it
338
        ld a, b                 ; retrieve param
339
        ld (hl), a              ; set vector table page address
340 213 winston
        pop hl
341 211 winston
        pop bc
342 213 winston
        ret                     ; FD is returned in L, address in HL
343 211 winston
 
344
;-------------------------------------------------------------------------
345
; F_freefd
346
; Frees the file descriptor passed in A.
347 384 winston
.globl F_freefd
348
F_freefd:
349 211 winston
        push hl
350 251 winston
        push af
351 211 winston
        ld h, v_fd1hwsock / 256
352
        ld l, a
353
        ld (hl), 0x80           ; Set bit 7 to mark the fd as freed.
354 384 winston
        add a, VECOFFS          ; add the vector table offset
355 211 winston
        ld l, a                 ; and point HL to it
356
        ld (hl), 0x00           ; clear it down
357 251 winston
        pop af
358 213 winston
        pop hl
359 211 winston
        ret
360
 
361
;------------------------------------------------------------------------
362
; F_allocdirhnd
363
; Allocates a directory handle.
364
; Parameters    A = ROM number for the handle
365 214 winston
; On return HL = address of the handle, L is the handle itself
366 384 winston
.globl F_allocdirhnd
367
F_allocdirhnd:
368 285 winston
        bit 0, c
369
        jr z, F_freedirhnd
370 211 winston
        push bc
371
        ld hl, v_dhnd1page
372
        ld b, MAX_DIRHNDS
373
        ex af, af'
374 384 winston
.findloop15:
375 211 winston
        ld a, (hl)
376
        and a                   ; 0 = free
377 384 winston
        jr z, .alloc15
378 211 winston
        inc l
379 384 winston
        djnz .findloop15
380 211 winston
        scf                     ; all are used up
381
        pop bc
382
        ret
383 384 winston
.alloc15:
384 211 winston
        ex af, af'
385
        ld (hl), a              ; allocate it by setting the page number
386
        pop bc
387
        ret
388
 
389
;-----------------------------------------------------------------------
390
; F_freedirhnd
391
; Frees the directory handle passed in A
392 384 winston
.globl F_freedirhnd
393
F_freedirhnd:
394 211 winston
        push hl
395
        ld h, v_dhnd1page / 256
396
        ld l, a
397
        ld (hl), 0
398
        pop hl
399
        ret
400 229 winston
 
401
;-----------------------------------------------------------------------
402
; F_resolvemp
403
; Resolve the mount point from a path.
404
; The symbolic mount point can be 0:, 1:, 2:, 3:. Basically, the pattern
405
; is ^[0-3]: in regexp terms.
406
; HL = pointer to the string.
407
; Returns with A = mount point handle.
408 384 winston
.globl F_resolvemp
409
F_resolvemp:
410 230 winston
        push hl
411
        inc hl                  ; check for the :
412
        ld a, (hl)
413
        cp ':'
414 384 winston
        jr nz, .returncurrent17 ; Return the current mount point.
415 230 winston
        dec hl
416
        ld a, (hl)              ; Get the putative FS number
417
        sub '0'                 ; Subtract ascii '0' to make the actual number
418 384 winston
        jr c, .returncurrent17
419 230 winston
        cp 4                    ; Greater than 3?
420 384 winston
        jr nc, .returncurrent17
421 230 winston
        pop hl
422
        inc hl                  ; effectively strip off the "n:"
423
        inc hl
424
        ret
425 229 winston
 
426 384 winston
.returncurrent17:
427 230 winston
        pop hl
428
        ld a, (v_vfs_curmount)
429
        ret
430 229 winston
 
431 251 winston
;----------------------------------------------------------------------
432
; F_cleanpath
433
; Gets rid of leading/trailing white spaces
434 384 winston
.globl F_cleanpath
435
F_cleanpath:
436 251 winston
        push hl
437
        ld bc, 256
438
        xor a
439
        cpir                    ; find the argument's end
440
        dec hl                  ; end - 1
441 384 winston
.spaceloop18:
442 251 winston
        dec hl
443
        ld a, (hl)
444
        cp ' '
445 384 winston
        jr nz, .done18
446 251 winston
        ld (hl), 0              ; remove trailing white space
447 384 winston
        jr .spaceloop18
448
.done18:
449 251 winston
        pop hl
450
        ret
451