]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/gb/ev.c
demote libemu to common code
[plan9front.git] / sys / src / games / gb / ev.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 Event evhblank, evtimer, evenv;
8 extern Event evsamp, chev[4];
9 Event *events[NEVENT] = {&evhblank, &evtimer, &evenv, &evsamp, &chev[0], &chev[1], &chev[2], &chev[3]};
10 Event *elist;
11 static int timshtab[4] = {12, 4, 6, 8}, timsh;
12 ulong timclock;
13 Var evvars[] = {VAR(timsh), VAR(timclock), {nil, 0, 0}};
14
15 void
16 addevent(Event *ev, int time)
17 {
18         Event **p, *e;
19         int t;
20         
21         assert(time >= 0);
22         t = time;
23         for(p = &elist; (e = *p) != nil; p = &e->next){
24                 if(t < e->time){
25                         e->time -= t;
26                         break;
27                 }
28                 t -= e->time;
29         }
30         ev->next = e;
31         ev->time = t;
32         *p = ev;
33 }
34
35 void
36 delevent(Event *ev)
37 {
38         Event **p, *e;
39         
40         for(p = &elist; (e = *p) != nil; p = &e->next)
41                 if(e == ev){
42                         *p = e->next;
43                         if(e->next != nil)
44                                 e->next->time += e->time;
45                         return;
46                 }
47 }
48
49 void
50 popevent(void)
51 {
52         Event *e;
53         int t;
54         
55         do{
56                 e = elist;
57                 t = e->time;
58                 elist = e->next;
59                 e->f(e->aux);
60         }while((elist->time += t) <= 0);
61 }
62
63 void
64 timerset(void)
65 {
66         timclock = clock & -(1<<timsh);
67         if((reg[TAC] & 4) != 0){
68                 delevent(&evtimer);
69                 addevent(&evtimer, 0x100 - reg[TIMA] << timsh);// | -clock & (1<<timsh)-1);
70         }
71 }
72
73 void
74 timertac(u8int n, int t)
75 {
76         if((reg[TAC] & 7) == (n & 7) && !t)
77                 return;
78         if((reg[TAC] & 4) != 0){
79                 delevent(&evtimer);
80                 reg[TIMA] += clock - timclock >> timsh;
81         }
82         timclock = clock & -(1<<timsh);
83         timsh = timshtab[n & 3];
84         if((mode & TURBO) == 0)
85                  timsh++;
86         if((n & 4) != 0)
87                 addevent(&evtimer, 0x100 - reg[TIMA] << timsh | -clock & (1<<timsh)-1);
88 }
89
90 u8int
91 timread(void)
92 {
93         if((reg[TAC] & 4) == 0)
94                 return reg[TIMA];
95         return reg[TIMA] + (clock - timclock >> timsh);
96 }
97
98 void
99 timertick(void *)
100 {
101         reg[TIMA] = reg[TMA];
102         addevent(&evtimer, 0x100 - reg[TIMA] << timsh);
103         reg[IF] |= IRQTIM;
104 }
105
106 void
107 eventinit(void)
108 {
109         extern void hblanktick(void *);
110         extern void envtick(void *);
111         extern void wavetick(void *);
112         extern void chantick(void *);
113         
114         evhblank.f = hblanktick;
115         addevent(&evhblank, 240*4);
116         evtimer.f = timertick;
117         evenv.f = envtick;
118         addevent(&evenv, FREQ / 512);
119         chev[0].f = chantick;
120         chev[1].f = chantick;
121         chev[2].f = chantick;
122         chev[3].f = chantick;
123 }