diff --git a/base_image/startup.cfg b/base_image/startup.cfg new file mode 100644 index 0000000..eb3ef56 --- /dev/null +++ b/base_image/startup.cfg @@ -0,0 +1 @@ +launcherfxf diff --git a/build.sh b/build.sh index 9b991b0..76232a5 100755 --- a/build.sh +++ b/build.sh @@ -13,6 +13,13 @@ fi echo "assembling kernel" ../fox32asm/target/release/fox32asm kernel/main.asm base_image/system.bin +echo "assembling launcher" +../fox32asm/target/release/fox32asm launcher/main.asm base_image/launcher.fxf + +echo "creating wallpapr.raw" +../tools/gfx2inc/target/release/gfx2inc 640 480 launcher/wallpaper.png launcher/wallpaper.inc +../fox32asm/target/release/fox32asm launcher/wallpaper.inc base_image/wallpapr.raw + echo "adding files to fox32os.img" cd base_image for file in ./*; do diff --git a/launcher/about.asm b/launcher/about.asm new file mode 100644 index 0000000..f487574 --- /dev/null +++ b/launcher/about.asm @@ -0,0 +1,63 @@ +; about dialog + +; show the about dialog +; inputs: +; none +; outputs: +; none +about_dialog: + ; return if the dialog overlay is already enabled + in r0, 0x80000300 + cmp r0, 0 + ifnz ret + + ; set overlay position + mov r0, 64 + mov r1, 64 + mov r2, 0 + call move_overlay + + ; set overlay size + mov r0, 256 + mov r1, 128 + mov r2, 0 + call resize_overlay + + ; allocate memory for the overlay framebuffer + mov r0, 131072 ; 256x128x4 + call allocate_memory + cmp r0, 0 + ifz jmp allocate_error + mov [about_dialog_framebuffer_ptr], r0 + mov r1, 0 + call set_overlay_framebuffer_pointer + + ; fill the overlay with all black + mov r0, 0xFF000000 + mov r1, 0 + call fill_overlay + + ; enable it!! + mov r0, 0 + call enable_overlay + +about_dialog_event_loop: + call get_next_event + + ; did the user click the menu bar? + cmp r0, EVENT_TYPE_MENU_BAR_CLICK + ifz mov r0, menu_items_root + ifz call menu_bar_click_event + + ; is the user in a menu? + cmp r0, EVENT_TYPE_MENU_UPDATE + ifz call menu_update_event + + ; did the user click a menu item? + cmp r0, EVENT_TYPE_MENU_CLICK + ifz call menu_click_event + + call yield_task + jmp about_dialog_event_loop + +about_dialog_framebuffer_ptr: data.32 0 diff --git a/launcher/file.asm b/launcher/file.asm new file mode 100644 index 0000000..f7742f6 --- /dev/null +++ b/launcher/file.asm @@ -0,0 +1,78 @@ +; file helper routines + +; get a list of FXF files on disk 0 +; inputs: +; none +; outputs: +; r0: pointer to file name buffer +; r1: number of files +get_fxf_files: + push r2 + push r31 + + ; allocate a 341 byte array for the file name buffer + mov r0, 341 + call allocate_memory + cmp r0, 0 + ifz jmp allocate_error + mov [all_file_list_ptr], r0 + + ; read the list of files into the buffer + mov r1, 0 + call ryfs_get_file_list + mov [number_of_all_files], r0 + + ; allocate a 341 byte buffer for the FXF file name buffer + mov r0, 341 + call allocate_memory + cmp r0, 0 + ifz jmp allocate_error + mov [fxf_file_list_ptr], r0 + + mov r0, [all_file_list_ptr] + mov r1, [fxf_file_list_ptr] + mov [number_of_fxf_files], 0 + mov r31, [number_of_all_files] +get_fxf_files_loop: + push r0 + push r1 + add r0, 8 + mov r1, fxf_ext + mov r2, 3 + call compare_memory_bytes + ifnz jmp get_fxf_files_loop_not_fxf + inc [number_of_fxf_files] + pop r1 + pop r0 + mov r2, 11 + call copy_memory_bytes + add r0, 11 + add r1, 11 + loop get_fxf_files_loop + jmp get_fxf_files_end +get_fxf_files_loop_not_fxf: + pop r1 + pop r0 + add r0, 11 + loop get_fxf_files_loop +get_fxf_files_end: + ; free the "all files" buffer + mov r0, [all_file_list_ptr] + call free_memory + + ; return pointer to file name buffer and number of files + mov r0, [fxf_file_list_ptr] + mov r1, [number_of_fxf_files] + + pop r31 + pop r2 + ret + +; all files +all_file_list_ptr: data.32 0 +number_of_all_files: data.32 0 + +; FXF files only +fxf_file_list_ptr: data.32 0 +number_of_fxf_files: data.32 0 +fxf_ext: data.str "fxf" diff --git a/launcher/launch.asm b/launcher/launch.asm new file mode 100644 index 0000000..d0112eb --- /dev/null +++ b/launcher/launch.asm @@ -0,0 +1,76 @@ +; FXF launcher helper routines + +; launch an FXF binary from a menu item +; inputs: +; r3: Launcher menu item +; outputs: +; none, does not return (jumps to `entry` when task ends) +launch_fxf: + mov r0, menu_items_launcher_list + add r0, 3 ; point to the first launcher item string + mul r3, 10 + add r0, r3 ; r0 now points to the name of the FXF file to load + + ; copy the name into the launch_fxf_name buffer + mov r1, launch_fxf_name + mov r2, 8 + call copy_memory_bytes + + ; disable the menu bar + call disable_menu_bar + + ; open the file + mov r0, launch_fxf_name + mov r1, 0 + mov r2, launch_fxf_struct + call ryfs_open + + ; allocate memory for the binary + mov r0, launch_fxf_struct + call ryfs_get_size + call allocate_memory + cmp r0, 0 + ifz jmp allocate_error + mov [launch_fxf_binary_ptr], r0 + + ; read the file into memory + mov r0, launch_fxf_struct + mov r1, [launch_fxf_binary_ptr] + call ryfs_read_whole_file + + ; allocate a 64KiB stack + mov r0, 65536 + call allocate_memory + cmp r0, 0 + ifz jmp allocate_error + mov [launch_fxf_stack_ptr], r0 + + ; relocate the binary + mov r0, [launch_fxf_binary_ptr] + call parse_fxf_binary + + ; create a new task + mov r1, r0 + call get_unused_task_id + mov.8 [launch_fxf_task_id], r0 + mov r2, [launch_fxf_stack_ptr] + add r2, 65536 ; point to the end of the stack (stack grows down!!) + mov r3, [launch_fxf_binary_ptr] + mov r4, [launch_fxf_stack_ptr] + call new_task + + ; fall-through to launch_fxf_yield_loop + +; loop until the launched task ends +launch_fxf_yield_loop: + movz.8 r0, [launch_fxf_task_id] + call is_task_id_used + ifz jmp entry + call yield_task + rjmp launch_fxf_yield_loop + +launch_fxf_name: data.str " fxf" +launch_fxf_struct: data.32 0 data.32 0 +launch_fxf_task_id: data.8 0 +launch_fxf_binary_ptr: data.32 0 +launch_fxf_stack_ptr: data.32 0 diff --git a/launcher/main.asm b/launcher/main.asm new file mode 100644 index 0000000..9b53122 --- /dev/null +++ b/launcher/main.asm @@ -0,0 +1,77 @@ +; launcher + +entry: + ; disable all overlays except the mouse cursor + mov r31, 0x1E + mov r0, 0x80000300 +disable_all_overlays_loop: + out r0, 0 + inc r0 + loop disable_all_overlays_loop + + ; set up the menu bar + call enable_menu_bar + call clear_menu_bar + mov r0, menu_items_root + mov r1, 0xFFFFFFFF + call draw_menu_bar_root_items + + ; open the wallpaper file and draw it + mov r0, wallpaper_file_name + mov r1, 0 + mov r2, wallpaper_file_struct + call ryfs_open + cmp r0, 0 + ifz jmp skip_wallpaper + + ; read the wallpaper file directly into the background framebuffer + mov r0, 1228800 ; 640x480x4 + mov r1, wallpaper_file_struct + mov r2, 0x02000000 + call ryfs_read +skip_wallpaper: + ; build a list of FXF files and add them to the menu + call get_fxf_files + call add_fxf_files_to_launcher_menu + +event_loop: + call get_next_event + + ; did the user click the menu bar? + cmp r0, EVENT_TYPE_MENU_BAR_CLICK + ifz mov r0, menu_items_root + ifz call menu_bar_click_event + + ; is the user in a menu? + cmp r0, EVENT_TYPE_MENU_UPDATE + ifz call menu_update_event + + ; did the user click a menu item? + cmp r0, EVENT_TYPE_MENU_CLICK + ifz call menu_click_event + + call yield_task + jmp event_loop + +allocate_error: + mov r0, allocate_error_str + mov r1, 16 + mov r2, 32 + mov r3, 0xFFFFFFFF + mov r4, 0xFF000000 + call draw_str_to_background +hang: + rjmp hang +allocate_error_str: data.str "error while allocating memory" data.8 0 + +wallpaper_file_name: data.str "wallpaprraw" +wallpaper_file_struct: data.32 0 data.32 0 + + #include "about.asm" + #include "file.asm" + #include "launch.asm" + #include "menu.asm" + + ; include system defs + #include "../../fox32rom/fox32rom.def" + #include "../fox32os.def" diff --git a/launcher/menu.asm b/launcher/menu.asm new file mode 100644 index 0000000..0df755d --- /dev/null +++ b/launcher/menu.asm @@ -0,0 +1,105 @@ +; menu bar helper routines + +; add all FXF files to the Launcher menu +; THIS FREES [r0], ONLY CALL THIS ONCE +; inputs: +; r0: pointer to file name buffer +; r1: number of files +; outputs: +; none +add_fxf_files_to_launcher_menu: + push r0 + push r1 + push r2 + push r31 + + mov r31, r1 + mov r1, menu_items_launcher_list + mov.8 [r1], r31 ; set number of items + add r1, 3 ; point to first string + mov r2, 8 ; copy 8 bytes each +add_fxf_files_to_launcher_menu_loop: + call copy_memory_bytes + add r0, 11 ; point to next file name + add r1, 10 ; point to next menu item string + loop add_fxf_files_to_launcher_menu_loop + + pop r31 + pop r2 + pop r1 + pop r0 + call free_memory + ret + +menu_click_event: + ; r2 contains the clicked root menu + ; r3 contains the clicked menu item + + ; system + cmp r2, 0 + ifz jmp system_menu_click_event + + ; launcher + cmp r2, 1 + ifz jmp launch_fxf + + ret + +system_menu_click_event: + ; r2 contains the clicked root menu + ; r3 contains the clicked menu item + + cmp r3, 0 + ifz jmp about_dialog + + ; shut down + cmp r3, 1 + ifz icl + ifz halt + + ret + +menu_items_root: + data.8 2 ; number of menus + data.32 menu_items_system_list data.32 menu_items_system_name ; pointer to menu list, pointer to menu name + data.32 menu_items_launcher_list data.32 menu_items_launcher_name ; pointer to menu list, pointer to menu name +menu_items_system_name: + data.8 6 data.str "System" data.8 0x00 ; text length, text, null-terminator +menu_items_launcher_name: + data.8 8 data.str "Launcher" data.8 0x00 ; text length, text, null-terminator +menu_items_system_list: + data.8 2 ; number of items + data.8 11 ; menu width (usually longest item + 2) + data.8 5 data.str "About" data.8 0x00 ; text length, text, null-terminator + data.8 9 data.str "Shut Down" data.8 0x00 ; text length, text, null-terminator +menu_items_launcher_list: ; reserve enough room for up to 28 items + data.8 1 ; number of items + data.8 10 ; menu width (usually longest item + 2) + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator + data.8 8 data.str " " data.8 0x00 ; text length, text, null-terminator diff --git a/launcher/wallpaper.png b/launcher/wallpaper.png new file mode 100644 index 0000000..5e668f0 Binary files /dev/null and b/launcher/wallpaper.png differ