12#include "irx_imports.h"
18IRX_ID(
"Vblank_service", 1, 1);
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, (
int (*)(
void *))vblank_handler_base_beginning, &vblank_internals);
62 RegisterVblankHandler(1, 128, (
int (*)(
void *))vblank_handler_base_end, &vblank_internals);
63 RegisterIntrHandler(IOP_IRQ_VBLANK, 1, (
int (*)(
void *))irq_vblank_interrupt_handler, &vblank_internals);
64 RegisterIntrHandler(IOP_IRQ_EVBLANK, 1, (
int (*)(
void *))irq_evblank_interrupt_handler, &vblank_internals);
73 return &vblank_internals;
76int RegisterVblankHandler(
int startend,
int priority,
int (*handler)(
void *),
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 *))
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);
179 item_count = vbi->item_count;
182 iSetEventFlag(GetSystemStatusFlag(), 0x200);
183 item_count = vbi->item_count;
185 item = vbi->list_00.next;
186 vbi->item_count = item_count + 1;
187 if ( item != &vbi->list_00 )
194 item_tmp = item->next;
195 if ( item_vblank->callback(item_vblank->userdata) == 0 )
197 linked_list_remove(item);
198 linked_list_add_after(&vbi->list_free, item);
201 }
while ( item_tmp != &vbi->list_00 );
212 item = vbi->list_11.next;
213 list_tail = &vbi->list_11;
214 if ( item != list_tail )
221 item_tmp = item->next;
222 if ( item_vblank->callback(item_vblank->userdata) == 0 )
224 linked_list_remove(item);
225 linked_list_add_after(&vbi->list_free, item);
228 }
while ( item_tmp != list_tail );
233#define EF_VBLANK_START 1
234#define EF_VBLANK_END 4
236#define EF_NON_VBLANK 8
240 iSetEventFlag(vbi->ef, EF_VBLANK_START);
241 iSetEventFlag(vbi->ef, EF_VBLANK);
242 iClearEventFlag(vbi->ef, ~(9));
248 iSetEventFlag(vbi->ef, EF_VBLANK_END);
249 iSetEventFlag(vbi->ef, EF_NON_VBLANK);
250 iClearEventFlag(vbi->ef, ~(6));
254void WaitVblankStart()
256 WaitEventFlag(vblank_internals.ef, EF_VBLANK_START, WEF_OR, NULL);
261 WaitEventFlag(vblank_internals.ef, EF_VBLANK_END, WEF_OR, NULL);
266 WaitEventFlag(vblank_internals.ef, EF_VBLANK, WEF_OR, NULL);
271 WaitEventFlag(vblank_internals.ef, EF_NON_VBLANK, WEF_OR, NULL);
280static int linked_list_next_is_self(
const vblank_ll_t *ll)
282 return ll->next == ll;
287 ll->next->prev = ll->prev;
288 ll->prev->next = ll->next;
295 return ll->prev == ll->next;
302 ll2->prev = ll1->prev;
304 ll2->prev->next = ll2;
int CpuResumeIntr(int state)
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
int QueryIntrContext(void)
int CpuSuspendIntr(int *state)