diff --git a/kernel/main.asm b/kernel/main.asm index 8bb9503..b96414c 100644 --- a/kernel/main.asm +++ b/kernel/main.asm @@ -58,16 +58,18 @@ entry: call draw_format_str_to_background ; open startup.cfg - mov r0, startup_file + mov r0, startup_cfg mov r1, 0 - mov r2, startup_file_struct + mov r2, startup_cfg_struct call ryfs_open cmp r0, 0 ifz jmp boot_disk_1 - ; load the first 11 bytes of startup.cfg, overwriting the "startup cfg" string + ; load a startup task +load_startup_task: + ; load 11 bytes of startup.cfg into startup_file mov r0, 11 - mov r1, startup_file_struct + mov r1, startup_cfg_struct mov r2, startup_file call ryfs_read @@ -85,25 +87,54 @@ entry: call allocate_memory cmp r0, 0 ifz jmp memory_error + mov [startup_file_binary_ptr], r0 + + ; allocate 64KiB for the startup file's stack + mov r0, 65536 + call allocate_memory + cmp r0, 0 + ifz jmp memory_error + mov [startup_file_stack_ptr], r0 ; read the startup file into memory - mov r1, r0 mov r0, startup_file_struct + mov r1, [startup_file_binary_ptr] call ryfs_read_whole_file ; relocate and execute it as a new task -run_startup_task: mov r0, r1 call parse_fxf_binary mov r3, r1 mov r1, r0 - mov r0, 0 - mov r2, rsp + movz.8 r0, [next_task_id] + mov r2, [startup_file_stack_ptr] + add r2, 65536 sub r2, 4 - mov r4, 0 ; don't attempt to free any stack block if the task ends + mov r4, [startup_file_stack_ptr] call new_task - ; when the startup file yields for the first time, we'll end up back here. + ; when the startup file yields for the first time, we'll end up back here + ; now, check to see if startup.cfg has any other entries + ; we do this by checking to see if the size of startup.cfg is less than or equal to 12 * next_task_id bytes + inc.8 [next_task_id] + mov r0, startup_cfg_struct + call ryfs_get_size + movz.8 r1, [next_task_id] + mul r1, 12 + cmp r0, r1 + iflteq jmp no_other_tasks + + ; seek forward one byte to skip the linefeed + mov r0, startup_cfg_struct + call ryfs_tell + inc r0 + mov r1, startup_cfg_struct + call ryfs_seek + + ; load the next task + jmp load_startup_task + +no_other_tasks: ; jump back to it without adding this "task" (not really a task) into the queue. ; end_current_task_no_mark_no_free is used specifically because it doesn't mark ; the current task (still set to 0) as unused, and it doesn't free the memory @@ -144,7 +175,16 @@ boot_disk_1_loop: loop boot_disk_1_loop mov r1, r5 - jmp run_startup_task + mov r0, r5 + call parse_fxf_binary + mov r3, r1 + mov r1, r0 + movz.8 r0, [next_task_id] + mov r2, rsp + sub r2, 4 + mov r4, 0 ; don't attempt to free any stack block if the task ends + call new_task + call end_current_task_no_mark_no_free startup_error: mov r0, BACKGROUND_COLOR @@ -188,10 +228,15 @@ get_os_version: startup_str: data.str "fox32 - OS version %u.%u.%u" data.8 0 startup_error_str: data.str "fox32 - OS version %u.%u.%u - startup.cfg is invalid!" data.8 0 -memory_error_str: data.str "fox32 - OS version %u.%u.%u - not enough memory to load startup file!" data.8 0 +memory_error_str: data.str "fox32 - OS version %u.%u.%u - not enough memory to perform operation!" data.8 0 -startup_file: data.str "startup cfg" +next_task_id: data.8 0 +startup_cfg: data.str "startup cfg" +startup_cfg_struct: data.32 0 data.32 0 +startup_file: data.str " " startup_file_struct: data.32 0 data.32 0 +startup_file_binary_ptr: data.32 0 +startup_file_stack_ptr: data.32 0 #include "../../fox32rom/fox32rom.def"