Subversion Repositories Spectranet

[/] [trunk/] [rom/] [vfs.asm] - Blame information for rev 570

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 399 winston
.include        "moduledefs.inc"
61
.include        "sysvars.inc"
62
.include        "sysdefs.inc"
63
.include        "sockdefs.inc"
64 570 winston
.include    "errno.inc"
65 399 winston
 
66 211 winston
;----------------------------------------------------------------------------
67
; Dispatcher routines.
68 399 winston
.globl F_fd_dispatch
69
F_fd_dispatch:
70 211 winston
        ex (sp), hl             ; fetch return address, saving HL
71
        push de
72 213 winston
        ld d, 0x3F              ; point DE at memory address containing
73
        ld e, a                 ; the fd's flags
74
        ex de, hl
75
        bit CLOSEDBIT, (hl)
76
        ex de, hl
77 214 winston
        jr nz, J_notopen
78 211 winston
        ld de, FDVECBASE        ; set base address of the descriptor table
79
        jr F_dispatch
80 399 winston
J_notopen:
81 213 winston
        pop de
82 218 winston
        pop hl
83 399 winston
        ld a, 0x06              ; TODO: errno.asm1 - EBADF
84 213 winston
        scf
85
        ret
86 211 winston
 
87 399 winston
.globl F_vfs_dispatch
88
F_vfs_dispatch:
89 251 winston
        call F_cleanpath        ; remove leading/trailing space
90 230 winston
        call F_resolvemp        ; See if a mount point is specified
91 443 winston
.globl F_umount                 ; (note that this is just the entry point
92
F_umount:                       ; for unmounting because the mount point
93
        ex (sp), hl             ; is already supplied in the accumulator)
94 211 winston
        push de
95 218 winston
        push af
96 211 winston
        ld de, VFSVECBASE
97 218 winston
        add a, e                ; find the address of the VFS vector
98
        ld e, a                 ; and check that something is mounted
99
        ld a, (de)
100
        and a                   ; not mounted if the VFS ROM no. was 0
101
        jr nz, F_dispatch_3
102 399 winston
.notmounted2:
103 218 winston
        pop af                  ; fix the stack
104
        pop de
105
        pop hl
106 399 winston
        ld a, 0x23              ; TODO: errno.asm2
107 218 winston
        scf
108
        ret
109 211 winston
 
110 399 winston
.globl F_dir_dispatch
111
F_dir_dispatch:
112 211 winston
        ex (sp), hl
113
        push de
114 214 winston
        ld d, 0x3F              ; point DE at the address containing
115
        ld e, a                 ; directory handle information
116
        ex af, af'
117
        ld a, (de)
118
        and a                   ; is this a valid open descriptor?
119
        jr z, J_notopen
120
        ex af, af'
121
        push af
122
        jr F_dispatch_2
123 211 winston
 
124
;--------------------------------------------------------------------------
125
; F_dispatch
126
; Find the appropriate ROM page for the file (or whatever) descriptor,
127
; and fetch the jump address from the jump table within.
128 399 winston
.globl F_dispatch_notfd
129
F_dispatch_notfd:
130 212 winston
        push af
131
        jr F_dispatch_1
132 399 winston
.globl F_dispatch
133
F_dispatch:
134 211 winston
        push af
135
        sub FDBASE%256
136 399 winston
.globl F_dispatch_1
137
F_dispatch_1:
138 211 winston
        add a, e                ; Calculate the address in the fd table
139 399 winston
.globl F_dispatch_2
140
F_dispatch_2:
141 211 winston
        ld e, a                 ; make DE point to it
142
        ld a, (de)              ; get the ROM to page
143
        and a                   ; ROM 0 is handled specially
144 218 winston
        jr z, isasocket
145 399 winston
.globl F_dispatch_3
146
F_dispatch_3:
147 214 winston
        ex af, af'              ; save AF while copying the current page
148 211 winston
        ld a, (v_pgb)           ; save current page
149
        ld (v_vfspgb_vecsave), a
150
        ex af, af'
151
        call F_setpageB         ; page the ROM
152
 
153
        ld a, l                 ; calculate the table offset for the function
154
        sub VFSJUMPOFFSET
155
        ld (VFSJUMP+1), a       ; set the jump vector
156
        pop af                  ; restore registers
157
        pop de
158
        pop hl
159
        call VFSJUMP
160
 
161
        push af                 ; restore original page B
162
        ld a, (v_vfspgb_vecsave)
163
        call F_setpageB
164
        pop af
165
        ret
166
 
167
; If someone access a socket via read/write rather than send/recv
168
; it's handled here. There are only four functions that can be done to
169
; a socket via the VFS interface.
170 399 winston
isasocket:
171 211 winston
        ld a, 0xCC              ; Check for READ. Note the LSB addresses
172
        cp l                    ; are +3 on the actual (because CALL put
173 399 winston
        jr z, .sockread8                ; the return address, not the actual
174 211 winston
        ld a, 0xCF              ; address on the stack!)
175
        cp l
176 399 winston
        jr z, .sockwrite8
177 211 winston
        ld a, 0xD8              ; POLL
178
        cp l
179 399 winston
        jr z, .sockpoll8
180 211 winston
        ld a, 0xD5              ; CLOSE
181 399 winston
        jr nz, .badcall8
182 211 winston
        pop af
183
        pop de
184
        pop hl
185
        jp F_sockclose
186 399 winston
.sockread8:
187 211 winston
        pop af
188
        pop de
189
        pop hl
190
        jp F_recv
191 399 winston
.sockwrite8:
192 211 winston
        pop af
193
        pop de
194
        pop hl
195
        jp F_send
196 399 winston
.sockpoll8:
197 211 winston
        pop af
198
        pop de
199
        pop hl
200
        jp F_pollfd
201 399 winston
.badcall8:
202 211 winston
        pop af
203
        pop de
204
        pop hl
205
        ld a, 0xFF              ; TODO: proper return code
206
        scf
207
        ret
208
 
209
;---------------------------------------------------------------------------
210
; F_mount
211
; Searches for an appropriate mount routines in the ROM modules we have,
212
; then tries to mount the FS.
213
; Parameters:           IX - pointer to an 10 byte structure that contains:
214
;                       byte 0,1 - pointer to null terminated protocol
215
;                       byte 2,3 - pointer to null terminated hostname
216
;                       byte 4,5 - pointer to null terminated mount source
217
;                       byte 6,7 - pointer to null terminated user id
218
;                       byte 8,9 - pointer to null terminated passwd
219
;                       A - device number
220
; The actual mount routine that gets called should do the following:
221
; - If the protocol is supported, mount the FS and return with Z and C reset
222
; - If the proto is supported, but the FS can't be mounted, return with C set
223
; - If the proto is not recognised, return with Z set
224 399 winston
.globl F_mount
225
F_mount:
226 211 winston
        ; First search for a ROM that handles this protocol.
227
        ld (v_mountnumber), a   ; save device number
228 570 winston
        add a,VFSVECBASE % 256  ; Add the vector table base address to
229
        ld l, a                 ; form the LSB of the table address to fill.
230
        ld h, 0x3F              ; 0x3F = system variables block
231
        ld a,(hl)
232
        cp 0
233
        jr nz, .notfree ; the mountpoint is in use
234
 
235
        ; search for a ROM that handles this protocol.
236
        ld a,(v_mountnumber)
237 211 winston
        ld hl, vectors
238 399 winston
.findrom9:
239 211 winston
        ld a, (hl)              ; get ROM ID
240
        and a                   ; check for the terminator
241 399 winston
        jr z, .notfound9                ; no ROM found that handles this protocol
242
.testproto9:
243 211 winston
        push hl                 ; save current vector table address
244
        ld a, l
245
        sub ROMVECOFFS          ; subtract the base addr to get the ROM slot
246
        push af                 ; save ROM slot number
247
        call F_pushpageB
248
        ld hl, (MOD_VEC_MOUNT)  ; get address of the real mount routine
249 214 winston
        ld a, h                 ; H must be 0x20-0x2F for a valid MOUNT routine
250
        and 0xF0                ; mask out low nibble
251
        cp 0x20                 ; result should be 0x20 for valid MOUNT
252 399 winston
        jr nz, .testnext9
253
        ld de, .return9         ; simulate CALL instruction with JP (HL)
254 211 winston
        push de
255 234 winston
        ld a, (v_mountnumber)
256 211 winston
        jp (hl)
257 399 winston
.return9:
258
        jr c, .mountfailed9     ; Tried but failed to mount?
259
        jr z, .testnext9                ; Protocol is not ours?
260 211 winston
        call F_poppageB         ; restore original page B
261
        pop af                  ; restore ROM page number
262
        pop hl                  ; restore the stack
263
        ret
264 399 winston
.testnext9:
265 211 winston
        call F_poppageB         ; restore stack
266
        pop af                  ; ROM slot number
267
        pop hl                  ; table pointer
268
        inc l                   ; and point it to the next ROM list entry
269 399 winston
        jr .findrom9
270 211 winston
 
271 399 winston
.mountfailed9:
272 319 winston
        ex af, af'
273 211 winston
        call F_poppageB         ; restore stack and page
274 319 winston
        pop af                  ; unwind stack
275 211 winston
        pop hl                  ; restore HL
276 319 winston
        ex af, af'
277 211 winston
        ret
278 570 winston
 
279
.notfree:
280
    ld a, TMPBUSY   ; mount point already used
281
    scf
282
    ret
283 399 winston
.notfound9:
284 570 winston
        ld a, TUNKPROTO ; unknown VFS protocol
285 211 winston
        scf
286
        ret
287 236 winston
 
288
;--------------------------------------------------------------------------
289
; F_freemountpoint
290
; Frees a mount point, passed in A
291 399 winston
.globl F_freemountpoint
292
F_freemountpoint:
293
        add a, VFSVECBASE % 256 ; calculate the address in sysvars
294 236 winston
        ld h, 0x3F              ; sysvars page
295
        ld l, a
296
        ld (hl), 0              ; clear it down
297
        ret
298 238 winston
 
299
;--------------------------------------------------------------------------
300
; F_setmountpoint
301
; Sets the default mountpoint in use, passed in A
302 399 winston
.globl F_setmountpoint
303
F_setmountpoint:
304 238 winston
        cp 4                    ; mount point must be <= 3
305
        ccf                     ; flip the carry flag
306
        ret c                   ; so if there's an error we return with C
307
        ld (v_vfs_curmount), a
308
        ret
309 285 winston
 
310 211 winston
;--------------------------------------------------------------------------
311 285 winston
; F_resalloc
312
; Resource allocator/deallocator for file and directory descriptors.
313
; Parameters: FD param in A
314
;             Flags in C
315
; C bit 0 = Set=Allocate, reset=free
316
; C bit 1 = Set=Directory, reset=File
317 399 winston
.globl F_resalloc
318
F_resalloc:
319 285 winston
        bit 1, c
320
        jr nz, F_allocdirhnd
321
;--------------------------------------------------------------------------
322 211 winston
; F_allocfd
323
; Allocates a file descriptor.
324
; Parameters:   A = ROM number for the fd
325
; On return HL = address of fd. Functions that use this should set this
326
; to a value that means something (and bit 7 must be reset). L = actual
327
; fd number.
328 399 winston
.globl F_allocfd
329
F_allocfd:
330 285 winston
        bit 0, c
331
        jr z, F_freefd
332 211 winston
        push bc
333
        ld hl, v_fd1hwsock      ; lowest address in fd table
334
        ld b, MAX_FDS
335 399 winston
.findloop13:
336 211 winston
        bit 7, (hl)             ; not allocated yet?
337 399 winston
        jr nz, .alloc13
338 211 winston
        inc l
339 399 winston
        djnz .findloop13                ; keep looking until none left
340 211 winston
        scf                     ; out of free file descriptors
341
        pop bc
342
        ret
343 399 winston
.alloc13:
344 213 winston
        res 7, (hl)             ; basic allocation
345
        push hl                 ; save FD address and FD number
346 211 winston
        ld b, a                 ; save parameter
347
        ld a, l
348 399 winston
        add a, VECOFFS          ; find the address of the vector table
349 211 winston
        ld l, a                 ; and make HL point to it
350
        ld a, b                 ; retrieve param
351
        ld (hl), a              ; set vector table page address
352 213 winston
        pop hl
353 211 winston
        pop bc
354 213 winston
        ret                     ; FD is returned in L, address in HL
355 211 winston
 
356
;-------------------------------------------------------------------------
357
; F_freefd
358
; Frees the file descriptor passed in A.
359 399 winston
.globl F_freefd
360
F_freefd:
361 211 winston
        push hl
362 251 winston
        push af
363 211 winston
        ld h, v_fd1hwsock / 256
364
        ld l, a
365
        ld (hl), 0x80           ; Set bit 7 to mark the fd as freed.
366 399 winston
        add a, VECOFFS          ; add the vector table offset
367 211 winston
        ld l, a                 ; and point HL to it
368
        ld (hl), 0x00           ; clear it down
369 251 winston
        pop af
370 213 winston
        pop hl
371 211 winston
        ret
372
 
373
;------------------------------------------------------------------------
374
; F_allocdirhnd
375
; Allocates a directory handle.
376
; Parameters    A = ROM number for the handle
377 214 winston
; On return HL = address of the handle, L is the handle itself
378 399 winston
.globl F_allocdirhnd
379
F_allocdirhnd:
380 285 winston
        bit 0, c
381
        jr z, F_freedirhnd
382 211 winston
        push bc
383
        ld hl, v_dhnd1page
384
        ld b, MAX_DIRHNDS
385
        ex af, af'
386 399 winston
.findloop15:
387 211 winston
        ld a, (hl)
388
        and a                   ; 0 = free
389 399 winston
        jr z, .alloc15
390 211 winston
        inc l
391 399 winston
        djnz .findloop15
392 211 winston
        scf                     ; all are used up
393
        pop bc
394
        ret
395 399 winston
.alloc15:
396 211 winston
        ex af, af'
397
        ld (hl), a              ; allocate it by setting the page number
398
        pop bc
399
        ret
400
 
401
;-----------------------------------------------------------------------
402
; F_freedirhnd
403
; Frees the directory handle passed in A
404 399 winston
.globl F_freedirhnd
405
F_freedirhnd:
406 211 winston
        push hl
407
        ld h, v_dhnd1page / 256
408
        ld l, a
409
        ld (hl), 0
410
        pop hl
411
        ret
412 229 winston
 
413
;-----------------------------------------------------------------------
414
; F_resolvemp
415
; Resolve the mount point from a path.
416
; The symbolic mount point can be 0:, 1:, 2:, 3:. Basically, the pattern
417
; is ^[0-3]: in regexp terms.
418
; HL = pointer to the string.
419
; Returns with A = mount point handle.
420 399 winston
.globl F_resolvemp
421
F_resolvemp:
422 230 winston
        push hl
423
        inc hl                  ; check for the :
424
        ld a, (hl)
425
        cp ':'
426 399 winston
        jr nz, .returncurrent17 ; Return the current mount point.
427 230 winston
        dec hl
428
        ld a, (hl)              ; Get the putative FS number
429
        sub '0'                 ; Subtract ascii '0' to make the actual number
430 399 winston
        jr c, .returncurrent17
431 230 winston
        cp 4                    ; Greater than 3?
432 399 winston
        jr nc, .returncurrent17
433 230 winston
        pop hl
434
        inc hl                  ; effectively strip off the "n:"
435
        inc hl
436
        ret
437 229 winston
 
438 399 winston
.returncurrent17:
439 230 winston
        pop hl
440
        ld a, (v_vfs_curmount)
441
        ret
442 229 winston
 
443 251 winston
;----------------------------------------------------------------------
444
; F_cleanpath
445
; Gets rid of leading/trailing white spaces
446 399 winston
.globl F_cleanpath
447
F_cleanpath:
448 251 winston
        push hl
449 483 winston
        push bc
450 251 winston
        ld bc, 256
451
        xor a
452
        cpir                    ; find the argument's end
453
        dec hl                  ; end - 1
454 399 winston
.spaceloop18:
455 251 winston
        dec hl
456
        ld a, (hl)
457
        cp ' '
458 399 winston
        jr nz, .done18
459 251 winston
        ld (hl), 0              ; remove trailing white space
460 399 winston
        jr .spaceloop18
461
.done18:
462 483 winston
        pop bc
463 251 winston
        pop hl
464
        ret
465