diff --git a/src/fs.rs b/src/fs.rs new file mode 100644 index 0000000..11257e3 --- /dev/null +++ b/src/fs.rs @@ -0,0 +1,83 @@ +use core::ffi::CStr; + +use crate::sys::file; + +#[repr(C, packed)] +pub struct FileCommand { + pub func: u32, // 0 = read, 1 = read folder, 2 = create/write + pub param1: u32, // offset (low) + pub param2: u32, // offset (high) or flags + pub param3: u32, // bytes to read/write + pub buf: *mut u8, // pointer to buffer + pub path: *const u8, // pointer to filename (ASCIIZ) +} + +pub fn read_file(offset: u32, bytes_to_read: u32, buf: &mut [u8], path: *const u8) -> u32 { + let mut info = FileCommand { + func: 0, + param1: offset, // file offset + param2: 0, // 0 + param3: bytes_to_read, // number of bytes to read + buf: buf.as_mut_ptr(), + path, + }; + + unsafe { + file(&mut info) + } +} + +#[repr(C, packed)] +pub struct FolderData { + pub version: u32, + pub len: u32, + pub files_count: u32, + _reserved: [u8; 20], + + blocks: [FolderDataBlock], +} + +#[repr(C, packed)] +pub struct FolderDataBlock { + pub attr: u32, + pub encoding: u32, + pub time_created: Time, + pub date_created: Date, + pub time_accessed: Time, + pub date_accessed: Date, + pub time_modified: Time, + pub date_modified: Date, + pub size: u64, + pub name: [u8; 264], +} + +#[repr(C, packed)] +pub struct Time { + pub seconds: u8, + pub minutes: u8, + pub hours: u8, + _reserved: u8, +} + +#[repr(C, packed)] +pub struct Date { + pub day: u8, + pub month: u8, + pub year: u16, + _reserved: u8, +} + +pub fn read_folder(offset: u32, blocks_to_read: u32, path: *const u8, buf: &mut [u8]) -> u32 { + let mut info = FileCommand { + func: 1, + param1: offset, + param2: 0, // encoding + param3: blocks_to_read, // number of blocks to read + buf: buf.as_mut_ptr(), + path, + }; + + unsafe { + file(&mut info) + } +} diff --git a/src/func_constants.inc b/src/func_constants.inc index cda41b6..840a3fb 100644 --- a/src/func_constants.inc +++ b/src/func_constants.inc @@ -9,9 +9,16 @@ SF_WAIT_EVENT = 10 SF_REDRAW = 12 SSF_BEGIN_DRAW = 1 SSF_END_DRAW = 2 +SF_RD_TO_FLOPPY = 16 SF_GET_BUTTON = 17 SF_SYSTEM_GET = 26 SSF_SYS_LANG = 5 +SF_CURRENT_FOLDER = 30 + SSF_SET_CF = 1 + SSF_GET_CF = 2 + SSF_ADD_SYS_FOLDER = 3 + SSF_SET_ENCODING = 4 + SSF_GET_ENCODING = 5 SF_SET_EVENTS_MASK = 40 SF_BOARD = 63 SSF_DEBUG_WRITE = 1 @@ -20,3 +27,4 @@ SF_SYS_MISC = 68 SSF_MEM_ALLOC = 12 SSF_MEM_FREE = 13 SSF_LOAD_DLL = 19 +SF_FILE = 70 diff --git a/src/lib.rs b/src/lib.rs index 296cdf8..a577206 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ mod nanolibc; pub mod allocation; pub mod dll; +pub mod fs; pub mod sys; pub use modules::*; diff --git a/src/sys.rs b/src/sys.rs index 41188e8..d2197d4 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -1,3 +1,5 @@ +use crate::fs::FileCommand; + #[link(name = "syscalls")] extern "C" { // -1 @@ -36,6 +38,10 @@ extern "C" { #[link_name = "_end_window_draw"] pub fn end_window_draw(); + // 16 + #[link_name = "_save_rd_to_floppy"] + pub fn save_rd_to_floppy(floppy: u32) -> u32; + // 17 #[link_name = "_get_button_id"] pub fn get_button_id() -> u32; @@ -44,6 +50,26 @@ extern "C" { #[link_name = "_get_lang"] pub fn get_lang() -> u32; + // 30.1 + #[link_name = "_set_current_folder"] + pub fn set_current_folder(folder: *const u8); + + // 30.2 + #[link_name = "_get_current_folder"] + pub fn get_current_folder(buffer: *mut u8, len: u32) -> u32; + + // 30.3 + #[link_name = "_add_sys_folder"] + pub fn add_sys_folder(folder: u32); + + // 30.4 + #[link_name = "_set_folder_encoding"] + pub fn set_folder_encoding(folder: u32, encoding: u32); + + // 30.5 + #[link_name = "_get_folder_encoding"] + pub fn get_folder_encoding(buffer: *mut u8, len: u32, encoding: *const u32) -> u32; + // 40 #[link_name = "_set_event_mask"] pub fn set_event_mask(mask: u32) -> u32; @@ -67,4 +93,8 @@ extern "C" { // 68.19 #[link_name = "_load_dll"] pub fn load_dll(name: *const u8) -> *const u32; + + // 70 + #[link_name = "_file"] + pub fn file(command: *const FileCommand) -> u32; } diff --git a/src/syscalls.S b/src/syscalls.S index 85570eb..47ce4dd 100644 --- a/src/syscalls.S +++ b/src/syscalls.S @@ -6,6 +6,7 @@ section '.text' public _exit public _start_window_draw public _end_window_draw + public _save_rd_to_floppy public _define_window public _put_pixel public _display_message @@ -18,6 +19,11 @@ section '.text' public _alloc public _free public _get_lang + public _set_current_folder + public _get_current_folder + public _add_sys_folder + public _set_folder_encoding + public _get_folder_encoding public _load_dll public _set_event_mask @@ -37,6 +43,12 @@ _end_window_draw: int 0x40 ret +_save_rd_to_floppy: + mov eax, SF_RD_TO_FLOPPY + mov ebx, [esp + 4 * 1] + int 0x40 + ret + _define_window: push edi push esi @@ -130,6 +142,45 @@ _get_lang: int 0x40 ret +_set_current_folder: + mov eax, SF_CURRENT_FOLDER + mov ebx, SSF_SET_CF + mov ecx, [esp + 4 * 1] + int 0x40 + ret + +_get_current_folder: + mov eax, SF_CURRENT_FOLDER + mov ebx, SSF_GET_CF + mov ecx, [esp + 4 * 1] + mov edx, [esp + 4 * 2] + int 0x40 + ret + +_add_sys_folder: + mov eax, SF_CURRENT_FOLDER + mov ebx, SSF_ADD_SYS_FOLDER + mov ecx, [esp + 4 * 1] + int 0x40 + ret + +_set_folder_encoding: + mov eax, SF_CURRENT_FOLDER + mov ebx, SSF_SET_ENCODING + mov ecx, [esp + 4 * 1] + mov edx, [esp + 4 * 2] + int 0x40 + ret + +_get_folder_encoding: + mov eax, SF_CURRENT_FOLDER + mov ebx, SSF_SET_ENCODING + mov ecx, [esp + 4 * 1] + mov edx, [esp + 4 * 2] + mov esi, [esp + 4 * 3] + int 0x40 + ret + _load_dll: mov eax, SF_SYS_MISC mov ebx, SSF_LOAD_DLL @@ -143,3 +194,8 @@ _set_event_mask: int 0x40 ret +_file: + mov eax, SF_FILE + mov ebx, [esp + 4 * 1] + int 0x40 + ret