Subversion Repositories Spectranet

[/] [branches/] [gnubinutils/] [rom/] [vfs.asm] - Diff between revs 371 and 384

Show entire file | Details | Blame | View Log

Rev 371 Rev 384
Line 55... Line 55...
; 0x2043:       CLOSEDIR
; 0x2043:       CLOSEDIR
;
;
; For functions that are not implemented, an address to a short routine
; For functions that are not implemented, an address to a short routine
; that sets the carry flag and makes A the appropriate return code should
; that sets the carry flag and makes A the appropriate return code should
; be provided.
; be provided.
        include "moduledefs.asm"
.include        "moduledefs.inc"
 
.include        "sysvars.inc"
 
.include        "sysdefs.inc"
 
.include        "sockdefs.inc"
 
 
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Dispatcher routines.
; Dispatcher routines.
F_fd_dispatch
.globl F_fd_dispatch
 
F_fd_dispatch:
        ex (sp), hl             ; fetch return address, saving HL
        ex (sp), hl             ; fetch return address, saving HL
        push de
        push de
        ld d, 0x3F              ; point DE at memory address containing
        ld d, 0x3F              ; point DE at memory address containing
        ld e, a                 ; the fd's flags
        ld e, a                 ; the fd's flags
        ex de, hl
        ex de, hl
        bit CLOSEDBIT, (hl)
        bit CLOSEDBIT, (hl)
        ex de, hl
        ex de, hl
        jr nz, J_notopen
        jr nz, J_notopen
        ld de, FDVECBASE        ; set base address of the descriptor table
        ld de, FDVECBASE        ; set base address of the descriptor table
        jr F_dispatch
        jr F_dispatch
J_notopen
J_notopen:
        pop de
        pop de
        pop hl
        pop hl
        ld a, 0x06              ; TODO: errno.asm - EBADF
        ld a, 0x06              ; TODO: errno.asm1 - EBADF
        scf
        scf
        ret
        ret
 
 
F_vfs_dispatch
.globl F_vfs_dispatch
 
F_vfs_dispatch:
        call F_cleanpath        ; remove leading/trailing space
        call F_cleanpath        ; remove leading/trailing space
        call F_resolvemp        ; See if a mount point is specified
        call F_resolvemp        ; See if a mount point is specified
        ex (sp), hl
        ex (sp), hl
        push de
        push de
        push af
        push af
Line 88... Line 94...
        add a, e                ; find the address of the VFS vector
        add a, e                ; find the address of the VFS vector
        ld e, a                 ; and check that something is mounted
        ld e, a                 ; and check that something is mounted
        ld a, (de)
        ld a, (de)
        and a                   ; not mounted if the VFS ROM no. was 0
        and a                   ; not mounted if the VFS ROM no. was 0
        jr nz, F_dispatch_3
        jr nz, F_dispatch_3
.notmounted
.notmounted2:
        pop af                  ; fix the stack
        pop af                  ; fix the stack
        pop de
        pop de
        pop hl
        pop hl
        ld a, 0x23              ; TODO: errno.asm
        ld a, 0x23              ; TODO: errno.asm2
        scf
        scf
        ret
        ret
 
 
F_dir_dispatch
.globl F_dir_dispatch
 
F_dir_dispatch:
        ex (sp), hl
        ex (sp), hl
        push de
        push de
        ld d, 0x3F              ; point DE at the address containing
        ld d, 0x3F              ; point DE at the address containing
        ld e, a                 ; directory handle information
        ld e, a                 ; directory handle information
        ex af, af'
        ex af, af'
Line 113... Line 120...
 
 
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; F_dispatch
; F_dispatch
; Find the appropriate ROM page for the file (or whatever) descriptor,
; Find the appropriate ROM page for the file (or whatever) descriptor,
; and fetch the jump address from the jump table within.
; and fetch the jump address from the jump table within.
F_dispatch_notfd
.globl F_dispatch_notfd
 
F_dispatch_notfd:
        push af
        push af
        jr F_dispatch_1
        jr F_dispatch_1
F_dispatch
.globl F_dispatch
 
F_dispatch:
        push af
        push af
        sub FDBASE%256
        sub FDBASE%256
F_dispatch_1
.globl F_dispatch_1
 
F_dispatch_1:
        add a, e                ; Calculate the address in the fd table
        add a, e                ; Calculate the address in the fd table
F_dispatch_2
.globl F_dispatch_2
 
F_dispatch_2:
        ld e, a                 ; make DE point to it
        ld e, a                 ; make DE point to it
        ld a, (de)              ; get the ROM to page
        ld a, (de)              ; get the ROM to page
        and a                   ; ROM 0 is handled specially
        and a                   ; ROM 0 is handled specially
        jr z, isasocket
        jr z, isasocket
F_dispatch_3
.globl F_dispatch_3
 
F_dispatch_3:
        ex af, af'              ; save AF while copying the current page
        ex af, af'              ; save AF while copying the current page
        ld a, (v_pgb)           ; save current page
        ld a, (v_pgb)           ; save current page
        ld (v_vfspgb_vecsave), a
        ld (v_vfspgb_vecsave), a
        ex af, af'
        ex af, af'
        call F_setpageB         ; page the ROM
        call F_setpageB         ; page the ROM
Line 150... Line 162...
        ret
        ret
 
 
; If someone access a socket via read/write rather than send/recv
; If someone access a socket via read/write rather than send/recv
; it's handled here. There are only four functions that can be done to
; it's handled here. There are only four functions that can be done to
; a socket via the VFS interface.
; a socket via the VFS interface.
isasocket
isasocket:
        ld a, 0xCC              ; Check for READ. Note the LSB addresses
        ld a, 0xCC              ; Check for READ. Note the LSB addresses
        cp l                    ; are +3 on the actual (because CALL put
        cp l                    ; are +3 on the actual (because CALL put
        jr z, .sockread         ; the return address, not the actual
        jr z, .sockread8                ; the return address, not the actual
        ld a, 0xCF              ; address on the stack!)
        ld a, 0xCF              ; address on the stack!)
        cp l
        cp l
        jr z, .sockwrite
        jr z, .sockwrite8
        ld a, 0xD8              ; POLL
        ld a, 0xD8              ; POLL
        cp l
        cp l
        jr z, .sockpoll
        jr z, .sockpoll8
        ld a, 0xD5              ; CLOSE
        ld a, 0xD5              ; CLOSE
        jr nz, .badcall
        jr nz, .badcall8
        pop af
        pop af
        pop de
        pop de
        pop hl
        pop hl
        jp F_sockclose
        jp F_sockclose
.sockread
.sockread8:
        pop af
        pop af
        pop de
        pop de
        pop hl
        pop hl
        jp F_recv
        jp F_recv
.sockwrite
.sockwrite8:
        pop af
        pop af
        pop de
        pop de
        pop hl
        pop hl
        jp F_send
        jp F_send
.sockpoll
.sockpoll8:
        pop af
        pop af
        pop de
        pop de
        pop hl
        pop hl
        jp F_pollfd
        jp F_pollfd
.badcall
.badcall8:
        pop af
        pop af
        pop de
        pop de
        pop hl
        pop hl
        ld a, 0xFF              ; TODO: proper return code
        ld a, 0xFF              ; TODO: proper return code
        scf
        scf
Line 204... Line 216...
;                       A - device number
;                       A - device number
; The actual mount routine that gets called should do the following:
; The actual mount routine that gets called should do the following:
; - If the protocol is supported, mount the FS and return with Z and C reset
; - If the protocol is supported, mount the FS and return with Z and C reset
; - If the proto is supported, but the FS can't be mounted, return with C set
; - If the proto is supported, but the FS can't be mounted, return with C set
; - If the proto is not recognised, return with Z set
; - If the proto is not recognised, return with Z set
F_mount
.globl F_mount
 
F_mount:
        ; First search for a ROM that handles this protocol.
        ; First search for a ROM that handles this protocol.
        ld (v_mountnumber), a   ; save device number
        ld (v_mountnumber), a   ; save device number
        ld hl, vectors
        ld hl, vectors
.findrom
.findrom9:
        ld a, (hl)              ; get ROM ID
        ld a, (hl)              ; get ROM ID
        and a                   ; check for the terminator
        and a                   ; check for the terminator
        jr z, .notfound         ; no ROM found that handles this protocol
        jr z, .notfound9                ; no ROM found that handles this protocol
.testproto
.testproto9:
        push hl                 ; save current vector table address
        push hl                 ; save current vector table address
        ld a, l
        ld a, l
        sub ROMVECOFFS          ; subtract the base addr to get the ROM slot
        sub ROMVECOFFS          ; subtract the base addr to get the ROM slot
        push af                 ; save ROM slot number
        push af                 ; save ROM slot number
        call F_pushpageB
        call F_pushpageB
        ld hl, (MOD_VEC_MOUNT)  ; get address of the real mount routine
        ld hl, (MOD_VEC_MOUNT)  ; get address of the real mount routine
        ld a, h                 ; H must be 0x20-0x2F for a valid MOUNT routine
        ld a, h                 ; H must be 0x20-0x2F for a valid MOUNT routine
        and 0xF0                ; mask out low nibble
        and 0xF0                ; mask out low nibble
        cp 0x20                 ; result should be 0x20 for valid MOUNT
        cp 0x20                 ; result should be 0x20 for valid MOUNT
        jr nz, .testnext
        jr nz, .testnext9
        ld de, .return          ; simulate CALL instruction with JP (HL)
        ld de, .return9         ; simulate CALL instruction with JP (HL)
        push de
        push de
        ld a, (v_mountnumber)
        ld a, (v_mountnumber)
        jp (hl)
        jp (hl)
.return
.return9:
        jr c, .mountfailed      ; Tried but failed to mount?
        jr c, .mountfailed9     ; Tried but failed to mount?
        jr z, .testnext         ; Protocol is not ours?
        jr z, .testnext9                ; Protocol is not ours?
        call F_poppageB         ; restore original page B
        call F_poppageB         ; restore original page B
        ld a, (v_mountnumber)   ; get device number
        ld a, (v_mountnumber)   ; get device number
        add VFSVECBASE%256      ; and calculate the address in sysvars
        add a, VFSVECBASE%256   ; and calculate the address in sysvars
        ld h, 0x3F              ; MSB of the sysvars area
        ld h, 0x3F              ; MSB of the sysvars area
        ld l, a                 ; LSB - HL now has the addr of the fs table
        ld l, a                 ; LSB - HL now has the addr of the fs table
        pop af                  ; restore ROM page number
        pop af                  ; restore ROM page number
        ld (hl), a              ; Put the ROM number in the filesystem table
        ld (hl), a              ; Put the ROM number in the filesystem table
        pop hl                  ; restore the stack
        pop hl                  ; restore the stack
        ret
        ret
.testnext
.testnext9:
        call F_poppageB         ; restore stack
        call F_poppageB         ; restore stack
        pop af                  ; ROM slot number
        pop af                  ; ROM slot number
        pop hl                  ; table pointer
        pop hl                  ; table pointer
        inc l                   ; and point it to the next ROM list entry
        inc l                   ; and point it to the next ROM list entry
        jr .findrom
        jr .findrom9
 
 
.mountfailed
.mountfailed9:
        ex af, af'
        ex af, af'
        call F_poppageB         ; restore stack and page
        call F_poppageB         ; restore stack and page
        pop af                  ; unwind stack
        pop af                  ; unwind stack
        pop hl                  ; restore HL
        pop hl                  ; restore HL
        ex af, af'
        ex af, af'
        ret
        ret
.notfound
.notfound9:
        ld a, 0xFE              ; TODO: proper return code here
        ld a, 0xFE              ; TODO: proper return code here
        scf
        scf
        ret
        ret
 
 
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; F_freemountpoint
; F_freemountpoint
; Frees a mount point, passed in A
; Frees a mount point, passed in A
F_freemountpoint
.globl F_freemountpoint
        add VFSVECBASE % 256    ; calculate the address in sysvars
F_freemountpoint:
 
        add a, VFSVECBASE % 256 ; calculate the address in sysvars
        ld h, 0x3F              ; sysvars page
        ld h, 0x3F              ; sysvars page
        ld l, a
        ld l, a
        ld (hl), 0              ; clear it down
        ld (hl), 0              ; clear it down
        ret
        ret
 
 
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; F_setmountpoint
; F_setmountpoint
; Sets the default mountpoint in use, passed in A
; Sets the default mountpoint in use, passed in A
F_setmountpoint
.globl F_setmountpoint
 
F_setmountpoint:
        cp 4                    ; mount point must be <= 3
        cp 4                    ; mount point must be <= 3
        ccf                     ; flip the carry flag
        ccf                     ; flip the carry flag
        ret c                   ; so if there's an error we return with C
        ret c                   ; so if there's an error we return with C
        ld (v_vfs_curmount), a
        ld (v_vfs_curmount), a
        ret
        ret
Line 285... Line 300...
; Resource allocator/deallocator for file and directory descriptors.
; Resource allocator/deallocator for file and directory descriptors.
; Parameters: FD param in A
; Parameters: FD param in A
;             Flags in C
;             Flags in C
; C bit 0 = Set=Allocate, reset=free
; C bit 0 = Set=Allocate, reset=free
; C bit 1 = Set=Directory, reset=File
; C bit 1 = Set=Directory, reset=File
F_resalloc
.globl F_resalloc
 
F_resalloc:
        bit 1, c
        bit 1, c
        jr nz, F_allocdirhnd
        jr nz, F_allocdirhnd
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; F_allocfd
; F_allocfd
; Allocates a file descriptor.
; Allocates a file descriptor.
; Parameters:   A = ROM number for the fd
; Parameters:   A = ROM number for the fd
; On return HL = address of fd. Functions that use this should set this
; On return HL = address of fd. Functions that use this should set this
; to a value that means something (and bit 7 must be reset). L = actual
; to a value that means something (and bit 7 must be reset). L = actual
; fd number.
; fd number.
F_allocfd
.globl F_allocfd
 
F_allocfd:
        bit 0, c
        bit 0, c
        jr z, F_freefd
        jr z, F_freefd
        push bc
        push bc
        ld hl, v_fd1hwsock      ; lowest address in fd table
        ld hl, v_fd1hwsock      ; lowest address in fd table
        ld b, MAX_FDS
        ld b, MAX_FDS
.findloop
.findloop13:
        bit 7, (hl)             ; not allocated yet?
        bit 7, (hl)             ; not allocated yet?
        jr nz, .alloc
        jr nz, .alloc13
        inc l
        inc l
        djnz .findloop          ; keep looking until none left
        djnz .findloop13                ; keep looking until none left
        scf                     ; out of free file descriptors
        scf                     ; out of free file descriptors
        pop bc
        pop bc
        ret
        ret
.alloc
.alloc13:
        res 7, (hl)             ; basic allocation
        res 7, (hl)             ; basic allocation
        push hl                 ; save FD address and FD number
        push hl                 ; save FD address and FD number
        ld b, a                 ; save parameter
        ld b, a                 ; save parameter
        ld a, l
        ld a, l
        add VECOFFS             ; find the address of the vector table
        add a, VECOFFS          ; find the address of the vector table
        ld l, a                 ; and make HL point to it
        ld l, a                 ; and make HL point to it
        ld a, b                 ; retrieve param
        ld a, b                 ; retrieve param
        ld (hl), a              ; set vector table page address
        ld (hl), a              ; set vector table page address
        pop hl
        pop hl
        pop bc
        pop bc
        ret                     ; FD is returned in L, address in HL
        ret                     ; FD is returned in L, address in HL
 
 
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
; F_freefd
; F_freefd
; Frees the file descriptor passed in A.
; Frees the file descriptor passed in A.
F_freefd
.globl F_freefd
 
F_freefd:
        push hl
        push hl
        push af
        push af
        ld h, v_fd1hwsock / 256
        ld h, v_fd1hwsock / 256
        ld l, a
        ld l, a
        ld (hl), 0x80           ; Set bit 7 to mark the fd as freed.
        ld (hl), 0x80           ; Set bit 7 to mark the fd as freed.
        add VECOFFS             ; add the vector table offset
        add a, VECOFFS          ; add the vector table offset
        ld l, a                 ; and point HL to it
        ld l, a                 ; and point HL to it
        ld (hl), 0x00           ; clear it down
        ld (hl), 0x00           ; clear it down
        pop af
        pop af
        pop hl
        pop hl
        ret
        ret
Line 343... Line 361...
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; F_allocdirhnd
; F_allocdirhnd
; Allocates a directory handle.
; Allocates a directory handle.
; Parameters    A = ROM number for the handle
; Parameters    A = ROM number for the handle
; On return HL = address of the handle, L is the handle itself
; On return HL = address of the handle, L is the handle itself
F_allocdirhnd
.globl F_allocdirhnd
 
F_allocdirhnd:
        bit 0, c
        bit 0, c
        jr z, F_freedirhnd
        jr z, F_freedirhnd
        push bc
        push bc
        ld hl, v_dhnd1page
        ld hl, v_dhnd1page
        ld b, MAX_DIRHNDS
        ld b, MAX_DIRHNDS
        ex af, af'
        ex af, af'
.findloop
.findloop15:
        ld a, (hl)
        ld a, (hl)
        and a                   ; 0 = free
        and a                   ; 0 = free
        jr z, .alloc
        jr z, .alloc15
        inc l
        inc l
        djnz .findloop
        djnz .findloop15
        scf                     ; all are used up
        scf                     ; all are used up
        pop bc
        pop bc
        ret
        ret
.alloc
.alloc15:
        ex af, af'
        ex af, af'
        ld (hl), a              ; allocate it by setting the page number
        ld (hl), a              ; allocate it by setting the page number
        pop bc
        pop bc
        ret
        ret
 
 
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
; F_freedirhnd
; F_freedirhnd
; Frees the directory handle passed in A
; Frees the directory handle passed in A
F_freedirhnd
.globl F_freedirhnd
 
F_freedirhnd:
        push hl
        push hl
        ld h, v_dhnd1page / 256
        ld h, v_dhnd1page / 256
        ld l, a
        ld l, a
        ld (hl), 0
        ld (hl), 0
        pop hl
        pop hl
Line 383... Line 403...
; Resolve the mount point from a path.
; Resolve the mount point from a path.
; The symbolic mount point can be 0:, 1:, 2:, 3:. Basically, the pattern
; The symbolic mount point can be 0:, 1:, 2:, 3:. Basically, the pattern
; is ^[0-3]: in regexp terms.
; is ^[0-3]: in regexp terms.
; HL = pointer to the string.
; HL = pointer to the string.
; Returns with A = mount point handle.
; Returns with A = mount point handle.
F_resolvemp
.globl F_resolvemp
 
F_resolvemp:
        push hl
        push hl
        inc hl                  ; check for the :
        inc hl                  ; check for the :
        ld a, (hl)
        ld a, (hl)
        cp ':'
        cp ':'
        jr nz, .returncurrent   ; Return the current mount point.
        jr nz, .returncurrent17 ; Return the current mount point.
        dec hl
        dec hl
        ld a, (hl)              ; Get the putative FS number
        ld a, (hl)              ; Get the putative FS number
        sub '0'                 ; Subtract ascii '0' to make the actual number
        sub '0'                 ; Subtract ascii '0' to make the actual number
        jr c, .returncurrent
        jr c, .returncurrent17
        cp 4                    ; Greater than 3?
        cp 4                    ; Greater than 3?
        jr nc, .returncurrent
        jr nc, .returncurrent17
        pop hl
        pop hl
        inc hl                  ; effectively strip off the "n:"
        inc hl                  ; effectively strip off the "n:"
        inc hl
        inc hl
        ret
        ret
 
 
.returncurrent
.returncurrent17:
        pop hl
        pop hl
        ld a, (v_vfs_curmount)
        ld a, (v_vfs_curmount)
        ret
        ret
 
 
;----------------------------------------------------------------------
;----------------------------------------------------------------------
; F_cleanpath
; F_cleanpath
; Gets rid of leading/trailing white spaces
; Gets rid of leading/trailing white spaces
F_cleanpath
.globl F_cleanpath
 
F_cleanpath:
        push hl
        push hl
        ld bc, 256
        ld bc, 256
        xor a
        xor a
        cpir                    ; find the argument's end
        cpir                    ; find the argument's end
        dec hl                  ; end - 1
        dec hl                  ; end - 1
.spaceloop
.spaceloop18:
        dec hl
        dec hl
        ld a, (hl)
        ld a, (hl)
        cp ' '
        cp ' '
        jr nz, .done
        jr nz, .done18
        ld (hl), 0              ; remove trailing white space
        ld (hl), 0              ; remove trailing white space
        jr .spaceloop
        jr .spaceloop18
.done
.done18:
        pop hl
        pop hl
        ret
        ret