Skip to content

Commit

Permalink
kernel + sh: Allow path to override disk ID parameter; allow opening …
Browse files Browse the repository at this point in the history
…root
  • Loading branch information
ry755 committed Feb 18, 2025
1 parent c971495 commit d99f78a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 24 deletions.
19 changes: 13 additions & 6 deletions applications/sh/commands/dir.asm
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ shell_dir_command:
mov r0, shell_dir_command_header_string
call print_str_to_terminal

mov.16 [shell_dir_command_file_dir], 0
call get_current_disk_id
mov.8 [shell_dir_command_file_disk], r0
mov.16 [shell_dir_command_file_dir], 1
call shell_parse_arguments
cmp r0, 0
ifnz call shell_dir_command_open_dir
cmp.16 [shell_dir_command_file_dir], 0
ifz ret

call get_current_disk_id
mov r1, r0
mov r0, shell_dir_command_list_buffer
movz.8 r1, [shell_dir_command_file_disk]
movz.16 r2, [shell_dir_command_file_dir]
call ryfs_get_file_list
cmp r0, 0
Expand Down Expand Up @@ -60,10 +63,9 @@ shell_dir_command_loop:

; get and print the file size
; call ryfs_open instead of open because this uses the internal filename style
call get_current_disk_id
mov r1, r0
mov r0, shell_dir_command_list_buffer
add r0, r3
movz.8 r1, [shell_dir_command_file_disk]
mov r2, shell_dir_command_temp_file_struct
push r3
movz.16 r3, [shell_dir_command_file_dir]
Expand Down Expand Up @@ -93,13 +95,18 @@ shell_dir_command_open_dir:
pop r0
mov r2, shell_dir_command_temp_file_struct
call open
mov [shell_dir_command_file_dir], r0
mov.16 [shell_dir_command_file_dir], r0
; `open` may have used a different disk depending on the path
; first byte of the file struct is the disk ID
mov r0, shell_dir_command_temp_file_struct
mov.8 [shell_dir_command_file_disk], [r0]
ret

shell_dir_command_list_buffer: data.fill 0, 341
shell_dir_command_file_buffer: data.fill 0, 9
shell_dir_command_type_buffer: data.fill 0, 4
shell_dir_command_file_dir: data.fill 0, 2
shell_dir_command_file_disk: data.fill 0, 1
shell_dir_command_temp_file_struct: data.fill 0, 32
shell_dir_command_header_string:
data.8 SET_COLOR data.8 0x20 data.8 1 ; set the color to green
Expand Down
74 changes: 56 additions & 18 deletions kernel/vfs/vfs.asm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ const TEMP_SECTOR_BUF: 0x01FFF808

; open a file from a RYFS-formatted disk, or a named stream
; inputs:
; r0: pointer to file name string (8.3 format if file, for example "testfile.txt" or "test.txt")
; r0: pointer to file or directory path string
; i.e. 0:/stuff/test1.txt (will override specified disk) or
; /stuff/test1.txt (will use specified disk) or
; test2.txt (will use current directory and specified disk) or
; /stuff (will return sector of directory) or
; / (will return sector of root directory)
; r1: disk ID (ignored if stream)
; r2: file struct: pointer to a blank 32 byte file struct
; outputs:
Expand All @@ -39,21 +44,23 @@ open:
cmp.8 [r0], ':'
ifz jmp open_stream

push r1
push r2
mov r2, r1
mov r1, 0
open_iterate_loop:
call iterate_dir_path
; r0: pointer to null-terminated path string, incremented past the first directory
; r1: directory sector containing file, or zero if failure
; if zero, then r1 points to the sector of the file itself
; r1: directory sector containing file, or sector of file, or zero if failure
; r2: disk ID
; r3: zero if r0 points to the final file and not another directory; non-zero otherwise
; r3: zero if r0 or r1 points to the final file and not another directory; non-zero otherwise
cmp r3, 0
ifnz rjmp open_iterate_loop
mov r3, r1 ; ryfs_open expects the directory sector in r3
mov r1, r2 ; ryfs_open expects the disk ID in r1
pop r2
pop r1
cmp r0, 0
ifz rjmp open_root

call convert_filename
cmp r0, 0
Expand Down Expand Up @@ -124,11 +131,24 @@ open_stream:
pop r1
mov r0, 0
ret
open_root:
mov r0, r3 ; return the directory sector directly
; now, fill out the file struct like `ryfs_open` usually would
mov.8 [r2], r1 ; file_disk
mov.16 [r2+1], r0 ; file_first_sector
mov [r2+3], 0 ; file_seek_offset
mov [r2+7], 0 ; file_system_type (0x00 for RYFS)
mov.16 [r2+8], 0 ; file_dir_sector FIXME: should this be zero if `file_first_sector` points to the root dir???
ret

; create a file on a RYFS-formatted disk, or open a named stream
; if target file already exists, it will be deleted and then re-created as a blank file
; inputs:
; r0: pointer to file name string (8.3 format if file, for example "testfile.txt" or "test.txt")
; r0: pointer to file path string
; i.e. 0:/stuff/test1.txt (will override specified disk) or
; /stuff/test1.txt (will use specified disk) or
; test2.txt (will use current directory and specified disk)
; do not use this for directories directly
; r1: disk ID (ignored if stream)
; r2: file struct: pointer to a blank 32 byte file struct
; r3: target file size
Expand All @@ -139,23 +159,25 @@ create:
cmp.8 [r0], ':'
ifz jmp open_stream

push r1
push r2
push r3
mov r2, r1
mov r1, 0
create_iterate_loop:
call iterate_dir_path
; r0: pointer to null-terminated path string, incremented past the first directory
; r1: directory sector containing file, or zero if failure
; if zero, then r1 points to the sector of the file itself
; r1: directory sector containing file, or sector of file, or zero if failure
; r2: disk ID
; r3: zero if r0 points to the final file and not another directory; non-zero otherwise
; r3: zero if r0 or r1 points to the final file and not another directory; non-zero otherwise
cmp r3, 0
ifnz rjmp create_iterate_loop
mov r4, r1 ; ryfs_create expects the directory sector in r4
mov r1, r2 ; ryfs_create expects the disk ID in r1
pop r3
pop r2
pop r1
cmp r0, 0
ifz ret

call convert_filename
cmp r0, 0
Expand Down Expand Up @@ -497,8 +519,8 @@ convert_filename_output_string: data.fill 0, 12
convert_filename_temp_file_struct: data.fill 0, 32

; iterate on a user-friendly directory path into its directory sector, and increment the path to the next '/'
; e.g. /stuff.dir/test.txt will return r0 = "test.txt", r1 = sector of stuff.dir, r2 = <disk ID>, r3 = 0
; /stuff.dir/another.dir/test.txt will return r0 = "another.dir/test.txt", r1 = sector of stuff.dir, r2 = <disk ID>, r3 = <non-zero>
; e.g. 2:/stuff.dir/test.txt will return r0 = "test.txt", r1 = sector of stuff.dir, r2 = 2, r3 = 0
; /stuff.dir/another.dir/test.txt will return r0 = "another.dir/test.txt", r1 = sector of stuff.dir, r2 = <input disk ID>, r3 = <non-zero>
; the .dir extension of directory names may be omitted as needed; /stuff.dir/test.txt and /stuff/test.txt are treated the same
; trailing slashes in directory names are allowed (e.g. /stuff/ is treated the same as /stuff which is treated the same as /stuff.dir)
; inputs:
Expand All @@ -507,11 +529,11 @@ convert_filename_temp_file_struct: data.fill 0, 32
; r2: disk ID
; outputs:
; r0: pointer to null-terminated path string, incremented past the first directory
; r1: directory sector containing file, or zero if failure
; if zero, then r1 points to the sector of the file itself
; r1: directory sector containing file, or sector of file, or zero if failure
; r2: disk ID
; r3: zero if r0 points to the final file and not another directory; non-zero otherwise
; r3: zero if r0 or r1 points to the final file and not another directory; non-zero otherwise
iterate_dir_path:
push r2
push r27
push r28
push r29
Expand All @@ -528,13 +550,23 @@ iterate_dir_path:
ifnz mov r29, r1 ; this isn't the first iteration
ifnz rjmp iterate_dir_path_continue

; this is the first iteration, should we start from the root or the task's current dir?
; this is the first iteration
; is there a disk ID?
cmp.8 [r27+1], ':'
ifnz rjmp iterate_dir_path_check_root
movz.8 r28, [r27]
sub r28, '0'
inc r27, 2
iterate_dir_path_check_root:
; should we start from the root or the task's current dir?
cmp.8 [r27], '/'
ifz mov r29, 0
ifz mov r29, 1 ; root dir
ifnz movz.16 r29, [current_directory]
iterate_dir_path_continue:
cmp.8 [r27], '/'
ifz inc r27
cmp.8 [r27], 0
ifz rjmp iterate_dir_path_root

mov r0, r27
call vfs_string_length
Expand All @@ -556,6 +588,12 @@ iterate_dir_path_continue:
ifz rjmp iterate_dir_path_final_file ; trailing slash ignored
cmp.8 [r2], 0
ifnz rjmp iterate_dir_path_not_final_file
rjmp iterate_dir_path_final_file
iterate_dir_path_root:
; the path we were given was simply "/" (with or without a disk ID)
; simply return 1 as the sector of the file, as that is the root dir
mov r29, 1
mov r0, 0
iterate_dir_path_final_file:
; this is the final file, no need to open it
mov r1, r29
Expand Down Expand Up @@ -603,11 +641,11 @@ iterate_dir_path_fail:
mov r1, 0
mov r3, 0
iterate_dir_path_ret:
mov r2, r28
pop r30
pop r29
pop r28
pop r27
pop r2
ret
iterate_dir_path_temp_file_struct: data.fill 0, 32
iterate_dir_path_ending_str: data.strz ".dir"
Expand Down

0 comments on commit d99f78a

Please sign in to comment.