diff --git a/boot.asm b/boot.asm index 219ec33..91efb2c 100644 --- a/boot.asm +++ b/boot.asm @@ -1,6 +1,9 @@ ; disk booting routines ; these are only used during booting, they are not exposed via the jump table +const KERNEL_FILE_STRUCT: 0x01FFF800 ; kernel.bin file struct is right above the system stack +kernel_file_name: data.str "kernel bin" data.8 0 + ; read disk 0 and attempt to figure out what type of disk it is, and load the correct binary into memory ; inputs: ; r0: disk size (bytes) @@ -18,13 +21,18 @@ start_boot_process: mov r3, 0x80003000 ; command to read a sector from disk 0 into memory mov r4, 0x80002000 ; command to set the location of the buffer - ; first, check to see if this is a FAT-formatted disk + ; first, check to see if this is a FAT-formatted disk or RYFS-formatted disk out r4, r2 ; set the memory buffer location out r3, 0 ; read sector 0 into the buffer cmp.8 [r2], 0xEB ; check for an x86 jmp instruction, indicating a possible FAT volume ifz jmp start_boot_process_fat cmp.8 [r2], 0xE9 ; check for an x86 jmp instruction, indicating a possible FAT volume ifz jmp start_boot_process_fat + out r3, 1 ; read sector 1 into the buffer + add r2, 2 + cmp.16 [r2], 0x5952 ; check for RYFS magic bytes + ifz jmp start_boot_process_ryfs + sub r2, 2 start_boot_process_raw_binary_sector_loop: out r4, r2 ; set the memory buffer location out r3, r0 ; read the current sector into memory @@ -33,7 +41,18 @@ start_boot_process_raw_binary_sector_loop: loop start_boot_process_raw_binary_sector_loop jmp start_boot_process_done start_boot_process_fat: - ; + jmp start_boot_process_fat +start_boot_process_ryfs: + ; open kernel.bin + 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 + mov r1, 0x00000800 + call ryfs_read_whole_file start_boot_process_done: ; done loading !!! ; now clean up and jump to the loaded binary @@ -53,4 +72,4 @@ boot_cleanup: ; disable the menu bar call disable_menu_bar - ret \ No newline at end of file + ret diff --git a/disk.asm b/disk.asm index fc9a010..3164806 100644 --- a/disk.asm +++ b/disk.asm @@ -1,5 +1,7 @@ ; disk routines +const TEMP_SECTOR_BUF: 0x01FFF808 + ; read a sector into the specified memory buffer ; inputs: ; r0: sector number diff --git a/main.asm b/main.asm index 7ff1dee..4f8d036 100644 --- a/main.asm +++ b/main.asm @@ -152,6 +152,7 @@ get_rom_version: #include "mouse.asm" #include "overlay.asm" #include "panic.asm" + #include "ryfs.asm" #include "vsync.asm" diff --git a/ryfs.asm b/ryfs.asm new file mode 100644 index 0000000..35fc240 --- /dev/null +++ b/ryfs.asm @@ -0,0 +1,111 @@ +; RYFS routines + +; 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 +; 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 + push r10 + + ; r10: pointer to file struct entry + mov r10, r2 + mov.8 [r10], r1 ; write file_disk + inc r10 + + push r0 + mov r0, 1 + mov r2, r3 + call read_sector + pop r0 + + ; point to the file name of the first directory entry + mov r1, r3 + add r1, 20 + mov r2, 11 ; compare 11 bytes +ryfs_open_find_dir_entry_loop: + call compare_memory_bytes + ifz jmp ryfs_open_found_dir_entry + add r1, 16 ; point to the file name in the next directory entry + jmp ryfs_open_find_dir_entry_loop ; FIXME: this never returns if the file wasn't found +ryfs_open_found_dir_entry: + sub r1, 4 ; point to first sector of this file + mov.16 [r10], [r1] ; write file_first_sector + add r10, 2 + mov [r10], 0 ; write file_seek_offset + inc r10 + mov.8 [r10], 0 ; write file_reserved + movz.16 r0, [r1] + + pop r10 + pop r2 + pop r1 + 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: +; r0: pointer to file struct +; 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 + push r2 + push r10 + push r11 + + mov r10, r0 + mov r11, r1 + + ; read the first sector into the temp buffer + movz.8 r1, [r0] ; file_disk + inc r0 + movz.16 r0, [r0] ; file_first_sector +ryfs_read_whole_file_sector_loop: + mov r2, TEMP_SECTOR_BUF + call read_sector + + ; copy the sector data to the destination buffer + mov r0, TEMP_SECTOR_BUF + add r0, 6 + mov r1, r11 + mov r2, 506 + call copy_memory_bytes + + ; check to see if this is the last sector + ; FIXME: if this is the last sector, it should respect the sector size field in the header + sub r0, 4 + cmp.16 [r0], 0 + ifz jmp ryfs_read_whole_file_last_sector + + ; there are more sectors left, load them + movz.16 r0, [r0] ; sector number + mov r1, [r10] ; file_disk + add r11, 506 + jmp ryfs_read_whole_file_sector_loop +ryfs_read_whole_file_last_sector: + pop r11 + pop r10 + pop r2 + pop r1 + pop r0 + ret