From 155eed220c033c5bc82b44423ced16dbe42fd897 Mon Sep 17 00:00:00 2001 From: Ry Date: Fri, 20 Jan 2023 18:50:40 -0800 Subject: [PATCH] Implement very basic RYFS write support; cannot write past end of files Bumps version to 0.7.0 --- fox32rom.def | 1 + main.asm | 3 +- ryfs.asm | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 1 deletion(-) diff --git a/fox32rom.def b/fox32rom.def index ee55e3c..0217333 100644 --- a/fox32rom.def +++ b/fox32rom.def @@ -77,6 +77,7 @@ ryfs_read_whole_file: jmp [0xF0045014] ryfs_get_size: jmp [0xF0045018] ryfs_get_file_list: jmp [0xF004501C] ryfs_tell: jmp [0xF0045020] +ryfs_write: jmp [0xF0045024] ; memory copy/compare jump table copy_memory_bytes: jmp [0xF0046000] diff --git a/main.asm b/main.asm index 16db261..e247dc4 100644 --- a/main.asm +++ b/main.asm @@ -3,7 +3,7 @@ org 0xF0000000 const FOX32ROM_VERSION_MAJOR: 0 -const FOX32ROM_VERSION_MINOR: 6 +const FOX32ROM_VERSION_MINOR: 7 const FOX32ROM_VERSION_PATCH: 0 const SYSTEM_STACK: 0x01FFF800 @@ -285,6 +285,7 @@ get_rom_version: data.32 ryfs_get_size data.32 ryfs_get_file_list data.32 ryfs_tell + data.32 ryfs_write ; memory copy/compare jump table org.pad 0xF0046000 diff --git a/ryfs.asm b/ryfs.asm index 6899486..eccb8da 100644 --- a/ryfs.asm +++ b/ryfs.asm @@ -258,6 +258,172 @@ ryfs_read_whole_file: pop r0 ret +; write specified number of bytes from the specified buffer +; THIS DOES NOT UPDATE THE TOTAL SIZE OF THE FILE; do not write past the end of a file, bad things will happen +; inputs: +; r0: number of bytes to write +; r1: pointer to file struct +; r2: pointer to source buffer +; outputs: +; none +ryfs_write: + push r0 + push r1 + push r2 + push r3 + push r4 + push r5 + push r10 + push r11 + push r12 + push r31 + + ; 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_write_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_write_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_write_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 from the source buffer to the temp buffer + mov r0, r2 + mov r1, TEMP_SECTOR_BUF + add r1, 6 + add r1, r5 ; add the seek offset + mov r2, r11 + call copy_memory_bytes + pop r2 + pop r1 + pop r0 + + push r0 + push r1 + push r2 + ; write this sector back out to disk + mov r0, r4 + movz.8 r1, [r1] ; file_disk + mov r2, TEMP_SECTOR_BUF + call write_sector + pop r2 + pop r1 + pop r0 + + ; this_sector = this_sector.next + mov r5, TEMP_SECTOR_BUF + add r5, 2 + movz.16 r5, [r5] + mov r4, r5 + + add r2, r11 + sub r10, r11 + ifnz jmp ryfs_write_sector_loop + + ; file_struct.file_seek_offset += input r0 + add r1, 3 + add [r1], r0 + + pop r31 + pop r12 + pop r11 + pop r10 + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + ret + ; get the exact size of a file ; inputs: ; r0: pointer to file struct