18IRX_ID(
"Vblank_service", 1, 1);
22static vblank_internals_t vblank_internals;
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);
28static void linked_list_set_self(vblank_ll_t *ll);
29static int linked_list_next_is_self(
const vblank_ll_t *ll);
30static void linked_list_remove(vblank_ll_t *ll);
31static void linked_list_add_after(vblank_ll_t *ll1, vblank_ll_t *ll2);
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);
71vblank_internals_t *GetVblankInternalData(
void)
73 return &vblank_internals;
76int RegisterVblankHandler(
int startend,
int priority,
int (*handler)(
void *userdata),
void *arg)
78 const vblank_ll_t *list;
80 vblank_item_t *item_new;
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 )
101 const vblank_item_t *item_vblank;
103 item_vblank = (vblank_item_t *)item;
104 if ( item_vblank->callback == handler )
107 return KE_FOUND_HANDLER;
110 }
while ( item != list );
113 for ( ; item != list; item = item->next )
115 const vblank_item_t *item_vblank;
117 item_vblank = (vblank_item_t *)item;
118 if ( priority < item_vblank->priority )
121 item_new = (vblank_item_t *)vblank_internals.list_free.next;
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))
134 const vblank_ll_t *list;
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;
153 const vblank_item_t *item_vblank;
155 item_vblank = (vblank_item_t *)item;
156 while ( item_vblank->callback != handler )
159 item_vblank = (vblank_item_t *)item;
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)
177 vblank_ll_t *item_tmp;
178 vblank_internals_t *vbi;
180 vbi = (vblank_internals_t *)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 )
193 vblank_item_t *item_vblank;
195 item_vblank = (vblank_item_t *)item;
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)
211 const vblank_ll_t *list_tail;
212 vblank_ll_t *item_tmp;
213 vblank_internals_t *vbi;
215 vbi = (vblank_internals_t *)userdata;
216 item = vbi->list_11.next;
217 list_tail = &vbi->list_11;
218 if ( item != list_tail )
222 vblank_item_t *item_vblank;
224 item_vblank = (vblank_item_t *)item;
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)
244 vblank_internals_t *vbi;
246 vbi = (vblank_internals_t *)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)
255 vblank_internals_t *vbi;
257 vbi = (vblank_internals_t *)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);
284static void linked_list_set_self(vblank_ll_t *ll)
290static int linked_list_next_is_self(
const vblank_ll_t *ll)
292 return ll->next == ll;
295static void linked_list_remove(vblank_ll_t *ll)
297 ll->next->prev = ll->prev;
298 ll->prev->next = ll->next;
303static int linked_list_is_circular(vblank_ll_t *ll)
305 return ll->prev == ll->next;
309static void linked_list_add_after(vblank_ll_t *ll1, vblank_ll_t *ll2)
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)