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:
parent
203822e4f6
commit
041cf206ec
196
event.asm
196
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
|
|
@ -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]
|
||||
|
|
7
main.asm
7
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
|
||||
|
|
23
menu.asm
23
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
|
||||
|
|
12
mouse.asm
12
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
|
||||
|
|
12
submenu.asm
12
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user