From 041cf206eca4a1ab927702400ab3567ea0cecbd2 Mon Sep 17 00:00:00 2001 From: ry755 Date: Fri, 11 Feb 2022 20:27:23 -0800 Subject: [PATCH] fox32rom: Use a FIFO queue for events instead of a LIFO stack Using a LIFO stack for events was a dumb idea in the first place, this should've been a FIFO queue from the beginning. This allows the system to respond to events in the same order that they are generated, instead of always responding to the newest event first. --- event.asm | 196 +++++++++++++++++++++++++++++++++------------------ fox32rom.def | 3 +- main.asm | 7 +- menu.asm | 23 +++--- mouse.asm | 12 +++- submenu.asm | 12 +++- 6 files changed, 160 insertions(+), 93 deletions(-) diff --git a/event.asm b/event.asm index 94ecc9b..41466b9 100644 --- a/event.asm +++ b/event.asm @@ -1,7 +1,11 @@ ; event system routines -const event_stack: 0x01FFFFFC ; pre-decremented -const event_stack_pointer: 0x01FFFFFC +const event_queue_top: 0x01FFFFFE +const event_queue_bottom: 0x01FFFBFE ; top - 0x400 (32 events * (4 bytes * (1 type + 7 parameters))) +const event_queue_index: 0x01FFFFFF ; byte +const event_queue_size: 32 ; 32 events +const event_size_bytes: 32 ; 32 bytes per event +const event_size_words: 8 ; 8 words per event ; event types const mouse_click_event_type: 0x00000000 @@ -15,112 +19,164 @@ const empty_event_type: 0xFFFFFFFF ; none ; outputs: ; r0: event type -; r1-r5: event parameters +; r1-r7: event parameters wait_for_event: ise halt - ; check the event stack pointer - ; if equal to its base address, then the event stack is empty - cmp [event_stack_pointer], event_stack_pointer + ; if the event queue index doesn't equal zero, then at least one event is available + cmp.8 [event_queue_index], 0 ifz jmp wait_for_event - ; an event is available in the event stack, pop it from the stack and return it - call pop_event + ; an event is available in the event queue, remove it from the queue and return it + call get_next_event ret -; push an event to the event stack +; add an event to the event queue ; inputs: ; r0: event type -; r1-r5: event parameters +; r1-r7: event parameters ; outputs: ; none -push_event: - push r6 +new_event: + ; ensure there is enough space left for another event + cmp.8 [event_queue_index], event_queue_size + ifz ret - mov r6, [event_stack_pointer] - ; TODO: check to make sure we don't accidentally clobber the system stack by pushing too many events + push r8 + push r9 - ; push r0 - sub r6, 4 - mov [r6], r0 + ; point to the current event queue index + mov r8, event_queue_bottom + movz.8 r9, [event_queue_index] + mul r9, event_size_bytes + add r8, r9 - ; push r1 - sub r6, 4 - mov [r6], r1 + ; copy the event type + mov [r8], r0 + add r8, 4 - ; push r2 - sub r6, 4 - mov [r6], r2 + ; copy the event parameters + mov [r8], r1 + add r8, 4 + mov [r8], r2 + add r8, 4 + mov [r8], r3 + add r8, 4 + mov [r8], r4 + add r8, 4 + mov [r8], r5 + add r8, 4 + mov [r8], r6 + add r8, 4 + mov [r8], r7 + add r8, 4 - ; push r3 - sub r6, 4 - mov [r6], r3 + ; increment the index + inc.8 [event_queue_index] - ; push r4 - sub r6, 4 - mov [r6], r4 - - ; push r5 - sub r6, 4 - mov [r6], r5 - - mov [event_stack_pointer], r6 - - pop r6 + pop r9 + pop r8 ret -; pop an event from the event stack +; get the next event and remove it from the event queue ; inputs: ; none ; outputs: ; r0: event type -; r1-r5: event parameters -pop_event: - ; check the event stack pointer - ; if equal to its base address, then the event stack is empty - cmp [event_stack_pointer], event_stack_pointer - ifz jmp pop_event_empty +; r1-r7: event parameters +get_next_event: + ; if the event queue index equals zero, then the queue is empty + cmp.8 [event_queue_index], 0 + ifz jmp get_next_event_empty - push r6 + icl + push r8 - mov r6, [event_stack_pointer] + ; point to the bottom of the event queue + mov r8, event_queue_bottom - ; pop r5 - mov r5, [r6] - add r6, 4 + ; copy the event type + mov r0, [r8] + add r8, 4 - ; pop r4 - mov r4, [r6] - add r6, 4 + ; copy the event parameters + mov r1, [r8] + add r8, 4 + mov r2, [r8] + add r8, 4 + mov r3, [r8] + add r8, 4 + mov r4, [r8] + add r8, 4 + mov r5, [r8] + add r8, 4 + mov r6, [r8] + add r8, 4 + mov r7, [r8] - ; pop r3 - mov r3, [r6] - add r6, 4 + ; shift all events down by one + call shift_events - ; pop r2 - mov r2, [r6] - add r6, 4 + ; decrement the index + dec.8 [event_queue_index] - ; pop r1 - mov r1, [r6] - add r6, 4 - - ; pop r0 - mov r0, [r6] - add r6, 4 - - mov [event_stack_pointer], r6 - - pop r6 + pop r8 + ise ret -pop_event_empty: +get_next_event_empty: mov r0, empty_event_type mov r1, 0 mov r2, 0 mov r3, 0 mov r4, 0 mov r5, 0 + mov r6, 0 + mov r7, 0 ret + +; shift all events down by one, overwriting the zero'th event +; inputs: +; none +; outputs: +; none +shift_events: + push r0 + push r1 + push r2 + push r3 + push r4 + + ; for (int i = 0; i < (event_queue_index - 1); i++) { + ; event_queue[i] = event_queue[i + 1]; + ; } + + movz.8 r31, [event_queue_index] + mov r3, 0 ; i + + ; source pointer: event_queue[i + 1] + mov r0, event_queue_bottom + mov r4, r3 + inc r4 + mul r4, event_size_words + add r0, r4 + + ; destination pointer: event_queue[i] + mov r1, event_queue_bottom + mov r4, r3 + mul r4, event_size_words + add r1, r4 + + ; size: event_size_words + mov r2, event_size_words + + call copy_memory_words + + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + ret \ No newline at end of file diff --git a/fox32rom.def b/fox32rom.def index 0862f94..481c830 100644 --- a/fox32rom.def +++ b/fox32rom.def @@ -3,8 +3,9 @@ ; system jump table entries system_vsync_handler: jmp [0xF1000000] get_mouse_position: jmp [0xF1000004] -push_event: jmp [0xF1000008] +new_event: jmp [0xF1000008] wait_for_event: jmp [0xF100000C] +get_next_event: jmp [0xF1000010] ; background jump table entries draw_str_to_background: jmp [0xF1001000] diff --git a/main.asm b/main.asm index 1c6f0bb..7604e36 100644 --- a/main.asm +++ b/main.asm @@ -8,7 +8,6 @@ const background_color: 0xFF414C50 ; initialization code entry: mov rsp, system_stack - mov [event_stack_pointer], event_stack mov [0x000003FC], system_vsync_handler @@ -110,8 +109,7 @@ draw_startup_text: ise event_loop: - halt - call pop_event + call get_next_event ; was the mouse clicked? cmp r0, mouse_click_event_type @@ -183,8 +181,9 @@ mount_boot_disk: org.pad 0xF1000000 data.32 system_vsync_handler data.32 get_mouse_position - data.32 push_event + data.32 new_event data.32 wait_for_event + data.32 get_next_event ; background jump table org.pad 0xF1001000 diff --git a/menu.asm b/menu.asm index 2bb2b9c..e4aa548 100644 --- a/menu.asm +++ b/menu.asm @@ -113,6 +113,8 @@ menu_bar_click_event: push r3 push r4 push r5 + push r6 + push r7 push r28 push r29 push r30 @@ -156,18 +158,7 @@ menu_bar_click_event_loop: ;mov r1, 0xFFFFFFFF ;call draw_menu_bar_root_items ; close_submenu already calls this call close_submenu - - pop r31 - pop r30 - pop r29 - pop r28 - pop r5 - pop r4 - pop r3 - pop r2 - pop r1 - pop r0 - ret + jmp menu_bar_click_event_end menu_bar_click_event_found_item: ; r30 contains the clicked root menu item (starting at 0) pop r0 @@ -182,13 +173,17 @@ menu_bar_click_event_found_item: mov r3, 0xFFFFFFFF ; event parameter 2: hovering submenu item (or 0xFFFFFFFF for none) mov r4, 0 mov r5, 0 + mov r6, 0 + mov r7, 0 mov r0, submenu_update_event_type - call push_event - + call new_event +menu_bar_click_event_end: pop r31 pop r30 pop r29 pop r28 + pop r7 + pop r6 pop r5 pop r4 pop r3 diff --git a/mouse.asm b/mouse.asm index aaae913..6e50d0b 100644 --- a/mouse.asm +++ b/mouse.asm @@ -34,6 +34,8 @@ mouse_update: push r3 push r4 push r5 + push r6 + push r7 mov r0, 0x8000001F ; overlay 31: position in r2, 0x80000401 ; mouse position @@ -75,8 +77,10 @@ mouse_update: mov r3, 0 mov r4, 0 mov r5, 0 + mov r6, 0 + mov r7, 0 mov r0, mouse_click_event_type ; set event type to mouse type - call push_event + call new_event jmp mouse_update_end mouse_update_menu_was_clicked: mov r2, r1 ; copy Y position to event parameter 1 @@ -84,9 +88,13 @@ mouse_update_menu_was_clicked: mov r3, 0 mov r4, 0 mov r5, 0 + mov r6, 0 + mov r7, 0 mov r0, menu_bar_click_event_type ; set event type to menu bar click type - call push_event + call new_event mouse_update_end: + pop r7 + pop r6 pop r5 pop r4 pop r3 diff --git a/submenu.asm b/submenu.asm index 569c778..3745a74 100644 --- a/submenu.asm +++ b/submenu.asm @@ -186,6 +186,8 @@ submenu_update_event: push r3 push r4 push r5 + push r6 + push r7 push r8 push r9 @@ -235,8 +237,10 @@ submenu_update_event_clicked: mov r3, r10 ; event parameter 2: selected submenu item mov r4, 0 mov r5, 0 + mov r6, 0 + mov r7, 0 mov r0, submenu_click_event_type - call push_event + call new_event mov r0, r1 call close_submenu jmp submenu_update_event_end_no_push @@ -247,11 +251,15 @@ submenu_update_event_end_push: mov r3, r10 ; event parameter 2: hovering submenu item (or 0xFFFFFFFF for none) mov r4, 0 mov r5, 0 + mov r6, 0 + mov r7, 0 mov r0, submenu_update_event_type - call push_event + call new_event submenu_update_event_end_no_push: pop r9 pop r8 + pop r7 + pop r6 pop r5 pop r4 pop r3