diff --git a/boot.asm b/boot.asm index b80e221..cc40208 100644 --- a/boot.asm +++ b/boot.asm @@ -60,7 +60,6 @@ start_boot_process_ryfs: mov r0, kernel_file_name mov r1, 0 mov r2, KERNEL_FILE_STRUCT - mov r3, TEMP_SECTOR_BUF call ryfs_open mov r0, KERNEL_FILE_STRUCT diff --git a/fox32rom.def b/fox32rom.def index 2bfdf41..71f553f 100644 --- a/fox32rom.def +++ b/fox32rom.def @@ -54,6 +54,10 @@ menu_update_event: jmp [0xF004401C] ; disk jump table read_sector: jmp [0xF0045000] write_sector: jmp [0xF0045004] +ryfs_open: jmp [0xF0045008] +ryfs_seek: jmp [0xF004500C] +ryfs_read: jmp [0xF0045010] +ryfs_read_whole_file: jmp [0xF0045014] ; memory copy/compare jump table copy_memory_bytes: jmp [0xF0046000] diff --git a/main.asm b/main.asm index c52b46c..5028350 100644 --- a/main.asm +++ b/main.asm @@ -192,6 +192,10 @@ get_rom_version: org.pad 0xF0045000 data.32 read_sector data.32 write_sector + data.32 ryfs_open + data.32 ryfs_seek + data.32 ryfs_read + data.32 ryfs_read_whole_file ; memory copy/compare jump table org.pad 0xF0046000 diff --git a/ryfs.asm b/ryfs.asm index 35fc240..79b1bd5 100644 --- a/ryfs.asm +++ b/ryfs.asm @@ -1,19 +1,18 @@ ; RYFS routines +; file struct: +; file_disk: 1 byte +; file_first_sector: 2 bytes +; file_seek_offset: 4 bytes +; file_reserved: 1 byte + ; open a file from a RYFS-formatted disk ; inputs: ; r0: pointer to file name string (8.3 format, for example "test txt" for test.txt) ; r1: disk ID -; r2: file struct: pointer to a blank 8 byte file struct as described below -; r3: pointer to sector buffer +; r2: file struct: pointer to a blank file struct ; outputs: ; r0: first file sector -; -; file struct: -; file_disk: 1 byte -; file_first_sector: 2 bytes -; file_seek_offset: 4 bytes -; file_reserved: 1 byte ryfs_open: push r1 push r2 @@ -26,12 +25,12 @@ ryfs_open: push r0 mov r0, 1 - mov r2, r3 + mov r2, TEMP_SECTOR_BUF call read_sector pop r0 ; point to the file name of the first directory entry - mov r1, r3 + mov r1, TEMP_SECTOR_BUF add r1, 20 mov r2, 11 ; compare 11 bytes ryfs_open_find_dir_entry_loop: @@ -53,6 +52,165 @@ ryfs_open_found_dir_entry: pop r1 ret +; seek specified file to the specified offset +; inputs: +; r0: byte offset +; r1: pointer to file struct +; outputs: +; none +ryfs_seek: + push r1 + + add r1, 3 + mov [r1], r0 + + pop r1 + ret + +; read specified number of bytes into the specified buffer +; inputs: +; r0: number of bytes to read +; r1: pointer to file struct +; r2: pointer to destination buffer +; outputs: +; none +ryfs_read: + push r0 + push r1 + push r2 + push r3 + push r4 + push r5 + push r10 + push r11 + push r12 + + ; number_of_sectors_to_load = ceil(input r0, 506) / 506 + + ; first, ceil the number of bytes to multiple of 506 + ; value_temp = value / 506 + ; if value % 506 != 0: + ; value_temp++ + ; value_ceil = value_temp * 506 + mov r10, r0 + mov r11, r0 + mov r12, 506 + div r11, r12 + rem r10, r12 + ifnz inc r11 + mul r11, r12 + div r11, r12 + mov r3, r11 ; r3: number_of_sectors_to_load + + mov r10, r1 + add r10, 3 + mov r4, [r10] + + mov r10, r4 + mov r11, r4 + mov r12, 506 + div r11, r12 + rem r10, r12 + ifnz inc r11 + mul r11, r12 + div r11, r12 + mov r4, r11 ; r4: number of sectors to traverse + + ; start_sector = traverse through linked sectors starting at file_struct.file_first_sector + + push r0 + push r1 + push r2 + mov r10, r1 + ; read the file's first sector into the temp buffer + movz.8 r1, [r10] ; file_disk + inc r10 + movz.16 r0, [r10] ; file_first_sector + mov r31, r4 +ryfs_read_traverse_sectors_loop: + mov r2, TEMP_SECTOR_BUF + call read_sector + mov r4, r0 + add r2, 2 ; point to next sector number + movz.16 r0, [r2] ; load next sector number + cmp r31, 0 ; if we started at zero, then don't attempt to loop + ifnz loop ryfs_read_traverse_sectors_loop + pop r2 + pop r1 + pop r0 + + ; r4: start_sector + + ; total_bytes_remaining = input r0 + ; this_sector = start_sector + ; for range 0..number_of_sectors_to_load: + ; load this_sector into temporary buffer + ; bytes_to_load = if total_bytes_remaining >= 506 + ; 506 + ; else: + ; total_bytes_remaining + ; for range 0..bytes_to_load: + ; load byte from temporary buffer into destination buffer + ; this_sector = this_sector.next + + mov r10, r0 ; r10: total_bytes_remaining +ryfs_read_sector_loop: + push r0 + push r1 + push r2 + ; read this sector into the temp buffer + mov r0, r4 + movz.8 r1, [r1] ; file_disk + mov r2, TEMP_SECTOR_BUF + call read_sector + pop r2 + pop r1 + pop r0 + + ; r11: bytes_to_load + cmp r10, 506 + ifgteq mov r11, 506 + iflt mov r11, r10 + + push r0 + push r1 + push r2 + + ; calculate the seek offset + mov r12, r1 + add r12, 3 + mov r5, [r12] + rem r5, 506 + + ; copy the sector data to the destination buffer + mov r0, TEMP_SECTOR_BUF + add r0, 6 + add r0, r5 ; add the seek offset + mov r1, r2 + mov r2, r11 + call copy_memory_bytes + pop r2 + pop r1 + pop r0 + + dec r10 + ifnz jmp ryfs_read_sector_loop + + ; file_struct.file_seek_offset += input r0 + add r1, 3 + add [r1], r0 + + pop r12 + pop r11 + pop r10 + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + ret + ; read a whole file into the specified buffer ; FIXME: this will always load a multiple of 506 bytes, even if the file is smaller ; inputs: @@ -60,12 +218,6 @@ ryfs_open_found_dir_entry: ; r1: pointer to destination buffer ; outputs: ; none -; -; file struct: -; file_disk: 1 byte -; file_first_sector: 2 bytes -; file_seek_offset: 4 bytes -; file_reserved: 1 byte ryfs_read_whole_file: push r0 push r1