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.
This commit is contained in:
ry755 2022-02-11 20:27:23 -08:00 committed by Ry
parent 203822e4f6
commit 041cf206ec
6 changed files with 160 additions and 93 deletions

196
event.asm
View File

@ -1,7 +1,11 @@
; event system routines ; event system routines
const event_stack: 0x01FFFFFC ; pre-decremented const event_queue_top: 0x01FFFFFE
const event_stack_pointer: 0x01FFFFFC 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 ; event types
const mouse_click_event_type: 0x00000000 const mouse_click_event_type: 0x00000000
@ -15,112 +19,164 @@ const empty_event_type: 0xFFFFFFFF
; none ; none
; outputs: ; outputs:
; r0: event type ; r0: event type
; r1-r5: event parameters ; r1-r7: event parameters
wait_for_event: wait_for_event:
ise ise
halt halt
; check the event stack pointer ; if the event queue index doesn't equal zero, then at least one event is available
; if equal to its base address, then the event stack is empty cmp.8 [event_queue_index], 0
cmp [event_stack_pointer], event_stack_pointer
ifz jmp wait_for_event ifz jmp wait_for_event
; an event is available in the event stack, pop it from the stack and return it ; an event is available in the event queue, remove it from the queue and return it
call pop_event call get_next_event
ret ret
; push an event to the event stack ; add an event to the event queue
; inputs: ; inputs:
; r0: event type ; r0: event type
; r1-r5: event parameters ; r1-r7: event parameters
; outputs: ; outputs:
; none ; none
push_event: new_event:
push r6 ; ensure there is enough space left for another event
cmp.8 [event_queue_index], event_queue_size
ifz ret
mov r6, [event_stack_pointer] push r8
; TODO: check to make sure we don't accidentally clobber the system stack by pushing too many events push r9
; push r0 ; point to the current event queue index
sub r6, 4 mov r8, event_queue_bottom
mov [r6], r0 movz.8 r9, [event_queue_index]
mul r9, event_size_bytes
add r8, r9
; push r1 ; copy the event type
sub r6, 4 mov [r8], r0
mov [r6], r1 add r8, 4
; push r2 ; copy the event parameters
sub r6, 4 mov [r8], r1
mov [r6], r2 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 ; increment the index
sub r6, 4 inc.8 [event_queue_index]
mov [r6], r3
; push r4 pop r9
sub r6, 4 pop r8
mov [r6], r4
; push r5
sub r6, 4
mov [r6], r5
mov [event_stack_pointer], r6
pop r6
ret ret
; pop an event from the event stack ; get the next event and remove it from the event queue
; inputs: ; inputs:
; none ; none
; outputs: ; outputs:
; r0: event type ; r0: event type
; r1-r5: event parameters ; r1-r7: event parameters
pop_event: get_next_event:
; check the event stack pointer ; if the event queue index equals zero, then the queue is empty
; if equal to its base address, then the event stack is empty cmp.8 [event_queue_index], 0
cmp [event_stack_pointer], event_stack_pointer ifz jmp get_next_event_empty
ifz jmp pop_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 ; copy the event type
mov r5, [r6] mov r0, [r8]
add r6, 4 add r8, 4
; pop r4 ; copy the event parameters
mov r4, [r6] mov r1, [r8]
add r6, 4 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 ; shift all events down by one
mov r3, [r6] call shift_events
add r6, 4
; pop r2 ; decrement the index
mov r2, [r6] dec.8 [event_queue_index]
add r6, 4
; pop r1 pop r8
mov r1, [r6] ise
add r6, 4
; pop r0
mov r0, [r6]
add r6, 4
mov [event_stack_pointer], r6
pop r6
ret ret
pop_event_empty: get_next_event_empty:
mov r0, empty_event_type mov r0, empty_event_type
mov r1, 0 mov r1, 0
mov r2, 0 mov r2, 0
mov r3, 0 mov r3, 0
mov r4, 0 mov r4, 0
mov r5, 0 mov r5, 0
mov r6, 0
mov r7, 0
ret 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

View File

@ -3,8 +3,9 @@
; system jump table entries ; system jump table entries
system_vsync_handler: jmp [0xF1000000] system_vsync_handler: jmp [0xF1000000]
get_mouse_position: jmp [0xF1000004] get_mouse_position: jmp [0xF1000004]
push_event: jmp [0xF1000008] new_event: jmp [0xF1000008]
wait_for_event: jmp [0xF100000C] wait_for_event: jmp [0xF100000C]
get_next_event: jmp [0xF1000010]
; background jump table entries ; background jump table entries
draw_str_to_background: jmp [0xF1001000] draw_str_to_background: jmp [0xF1001000]

View File

@ -8,7 +8,6 @@ const background_color: 0xFF414C50
; initialization code ; initialization code
entry: entry:
mov rsp, system_stack mov rsp, system_stack
mov [event_stack_pointer], event_stack
mov [0x000003FC], system_vsync_handler mov [0x000003FC], system_vsync_handler
@ -110,8 +109,7 @@ draw_startup_text:
ise ise
event_loop: event_loop:
halt call get_next_event
call pop_event
; was the mouse clicked? ; was the mouse clicked?
cmp r0, mouse_click_event_type cmp r0, mouse_click_event_type
@ -183,8 +181,9 @@ mount_boot_disk:
org.pad 0xF1000000 org.pad 0xF1000000
data.32 system_vsync_handler data.32 system_vsync_handler
data.32 get_mouse_position data.32 get_mouse_position
data.32 push_event data.32 new_event
data.32 wait_for_event data.32 wait_for_event
data.32 get_next_event
; background jump table ; background jump table
org.pad 0xF1001000 org.pad 0xF1001000

View File

@ -113,6 +113,8 @@ menu_bar_click_event:
push r3 push r3
push r4 push r4
push r5 push r5
push r6
push r7
push r28 push r28
push r29 push r29
push r30 push r30
@ -156,18 +158,7 @@ menu_bar_click_event_loop:
;mov r1, 0xFFFFFFFF ;mov r1, 0xFFFFFFFF
;call draw_menu_bar_root_items ; close_submenu already calls this ;call draw_menu_bar_root_items ; close_submenu already calls this
call close_submenu call close_submenu
jmp menu_bar_click_event_end
pop r31
pop r30
pop r29
pop r28
pop r5
pop r4
pop r3
pop r2
pop r1
pop r0
ret
menu_bar_click_event_found_item: menu_bar_click_event_found_item:
; r30 contains the clicked root menu item (starting at 0) ; r30 contains the clicked root menu item (starting at 0)
pop r0 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 r3, 0xFFFFFFFF ; event parameter 2: hovering submenu item (or 0xFFFFFFFF for none)
mov r4, 0 mov r4, 0
mov r5, 0 mov r5, 0
mov r6, 0
mov r7, 0
mov r0, submenu_update_event_type mov r0, submenu_update_event_type
call push_event call new_event
menu_bar_click_event_end:
pop r31 pop r31
pop r30 pop r30
pop r29 pop r29
pop r28 pop r28
pop r7
pop r6
pop r5 pop r5
pop r4 pop r4
pop r3 pop r3

View File

@ -34,6 +34,8 @@ mouse_update:
push r3 push r3
push r4 push r4
push r5 push r5
push r6
push r7
mov r0, 0x8000001F ; overlay 31: position mov r0, 0x8000001F ; overlay 31: position
in r2, 0x80000401 ; mouse position in r2, 0x80000401 ; mouse position
@ -75,8 +77,10 @@ mouse_update:
mov r3, 0 mov r3, 0
mov r4, 0 mov r4, 0
mov r5, 0 mov r5, 0
mov r6, 0
mov r7, 0
mov r0, mouse_click_event_type ; set event type to mouse type mov r0, mouse_click_event_type ; set event type to mouse type
call push_event call new_event
jmp mouse_update_end jmp mouse_update_end
mouse_update_menu_was_clicked: mouse_update_menu_was_clicked:
mov r2, r1 ; copy Y position to event parameter 1 mov r2, r1 ; copy Y position to event parameter 1
@ -84,9 +88,13 @@ mouse_update_menu_was_clicked:
mov r3, 0 mov r3, 0
mov r4, 0 mov r4, 0
mov r5, 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 mov r0, menu_bar_click_event_type ; set event type to menu bar click type
call push_event call new_event
mouse_update_end: mouse_update_end:
pop r7
pop r6
pop r5 pop r5
pop r4 pop r4
pop r3 pop r3

View File

@ -186,6 +186,8 @@ submenu_update_event:
push r3 push r3
push r4 push r4
push r5 push r5
push r6
push r7
push r8 push r8
push r9 push r9
@ -235,8 +237,10 @@ submenu_update_event_clicked:
mov r3, r10 ; event parameter 2: selected submenu item mov r3, r10 ; event parameter 2: selected submenu item
mov r4, 0 mov r4, 0
mov r5, 0 mov r5, 0
mov r6, 0
mov r7, 0
mov r0, submenu_click_event_type mov r0, submenu_click_event_type
call push_event call new_event
mov r0, r1 mov r0, r1
call close_submenu call close_submenu
jmp submenu_update_event_end_no_push 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 r3, r10 ; event parameter 2: hovering submenu item (or 0xFFFFFFFF for none)
mov r4, 0 mov r4, 0
mov r5, 0 mov r5, 0
mov r6, 0
mov r7, 0
mov r0, submenu_update_event_type mov r0, submenu_update_event_type
call push_event call new_event
submenu_update_event_end_no_push: submenu_update_event_end_no_push:
pop r9 pop r9
pop r8 pop r8
pop r7
pop r6
pop r5 pop r5
pop r4 pop r4
pop r3 pop r3