12#include "irx_imports.h"
18IRX_ID(
"Vblank_service", 1, 1);
24static int irq_vblank_interrupt_handler(
void *userdata);
25static int irq_evblank_interrupt_handler(
void *userdata);
26static int vblank_handler_base_beginning(
void *userdata);
27static int vblank_handler_base_end(
void *userdata);
29static int linked_list_next_is_self(
const vblank_ll_t *ll);
33int _start(
int ac,
char **av)
43 if ( RegisterLibraryEntries(&_exp_vblank) )
49 memset(&vblank_internals, 0,
sizeof(vblank_internals));
50 linked_list_set_self(&vblank_internals.list_00);
51 linked_list_set_self(&vblank_internals.list_11);
52 linked_list_set_self(&vblank_internals.list_free);
53 for ( i = 0; i < (
sizeof(vblank_internals.list_items) /
sizeof(vblank_internals.list_items[0])); i += 1 )
55 linked_list_add_after(&vblank_internals.list_free, &(vblank_internals.list_items[i].ll));
60 vblank_internals.ef = CreateEventFlag(&evfp);
61 RegisterVblankHandler(0, 128, vblank_handler_base_beginning, &vblank_internals);
62 RegisterVblankHandler(1, 128, vblank_handler_base_end, &vblank_internals);
73 return &vblank_internals;
76int RegisterVblankHandler(
int startend,
int priority,
int (*handler)(
void *userdata),
void *arg)
85 return KE_ILLEGAL_CONTEXT;
88 if ( linked_list_next_is_self(&vblank_internals.list_free) )
93 list = &vblank_internals.list_11;
95 list = &vblank_internals.list_00;
97 if ( list->next != list )
104 if ( item_vblank->callback == handler )
107 return KE_FOUND_HANDLER;
110 }
while ( item != list );
113 for ( ; item != list; item = item->next )
118 if ( priority < item_vblank->priority )
122 linked_list_remove(vblank_internals.list_free.next);
123 item_new->callback = handler;
124 item_new->userdata = arg;
125 item_new->priority = priority;
126 linked_list_add_after(item, &item_new->ll);
132int ReleaseVblankHandler(
int startend,
int (*handler)(
void *userdata))
140 return KE_ILLEGAL_CONTEXT;
143 list = &vblank_internals.list_11;
145 list = &vblank_internals.list_00;
147 if ( list->next == list )
150 return KE_NOTFOUND_HANDLER;
156 while ( item_vblank->callback != handler )
163 return KE_NOTFOUND_HANDLER;
167 linked_list_remove(item);
168 linked_list_add_after(&vblank_internals.list_free, item);
173static int irq_vblank_interrupt_handler(
void *userdata)
181 item_count = vbi->item_count;
184 iSetEventFlag(GetSystemStatusFlag(), 0x200);
185 item_count = vbi->item_count;
187 item = vbi->list_00.next;
188 vbi->item_count = item_count + 1;
189 if ( item != &vbi->list_00 )
196 item_tmp = item->next;
197 if ( item_vblank->callback(item_vblank->userdata) == 0 )
199 linked_list_remove(item);
200 linked_list_add_after(&vbi->list_free, item);
203 }
while ( item_tmp != &vbi->list_00 );
208static int irq_evblank_interrupt_handler(
void *userdata)
216 item = vbi->list_11.next;
217 list_tail = &vbi->list_11;
218 if ( item != list_tail )
225 item_tmp = item->next;
226 if ( item_vblank->callback(item_vblank->userdata) == 0 )
228 linked_list_remove(item);
229 linked_list_add_after(&vbi->list_free, item);
232 }
while ( item_tmp != list_tail );
237#define EF_VBLANK_START 1
238#define EF_VBLANK_END 4
240#define EF_NON_VBLANK 8
242static int vblank_handler_base_beginning(
void *userdata)
247 iSetEventFlag(vbi->ef, EF_VBLANK_START);
248 iSetEventFlag(vbi->ef, EF_VBLANK);
249 iClearEventFlag(vbi->ef, ~(9));
253static int vblank_handler_base_end(
void *userdata)
258 iSetEventFlag(vbi->ef, EF_VBLANK_END);
259 iSetEventFlag(vbi->ef, EF_NON_VBLANK);
260 iClearEventFlag(vbi->ef, ~(6));
264void WaitVblankStart()
266 WaitEventFlag(vblank_internals.ef, EF_VBLANK_START, WEF_OR, NULL);
271 WaitEventFlag(vblank_internals.ef, EF_VBLANK_END, WEF_OR, NULL);
276 WaitEventFlag(vblank_internals.ef, EF_VBLANK, WEF_OR, NULL);
281 WaitEventFlag(vblank_internals.ef, EF_NON_VBLANK, WEF_OR, NULL);
290static int linked_list_next_is_self(
const vblank_ll_t *ll)
292 return ll->next == ll;
297 ll->next->prev = ll->prev;
298 ll->prev->next = ll->next;
305 return ll->prev == ll->next;
312 ll2->prev = ll1->prev;
314 ll2->prev->next = ll2;
int CpuResumeIntr(int state)
int QueryIntrContext(void)
int CpuSuspendIntr(int *state)
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)