fox32rom/event.asm
ry755 041cf206ec 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.
2022-02-11 20:27:23 -08:00

182 lines
3.5 KiB
NASM

; event system routines
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
const menu_bar_click_event_type: 0x00000001
const submenu_update_event_type: 0x00000002
const submenu_click_event_type: 0x00000003
const empty_event_type: 0xFFFFFFFF
; block until an event is available
; inputs:
; none
; outputs:
; r0: event type
; r1-r7: event parameters
wait_for_event:
ise
halt
; 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 queue, remove it from the queue and return it
call get_next_event
ret
; add an event to the event queue
; inputs:
; r0: event type
; r1-r7: event parameters
; outputs:
; none
new_event:
; ensure there is enough space left for another event
cmp.8 [event_queue_index], event_queue_size
ifz ret
push r8
push r9
; 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
; copy the event type
mov [r8], r0
add r8, 4
; 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
; increment the index
inc.8 [event_queue_index]
pop r9
pop r8
ret
; get the next event and remove it from the event queue
; inputs:
; none
; outputs:
; r0: event type
; 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
icl
push r8
; point to the bottom of the event queue
mov r8, event_queue_bottom
; copy the event type
mov r0, [r8]
add r8, 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]
; shift all events down by one
call shift_events
; decrement the index
dec.8 [event_queue_index]
pop r8
ise
ret
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