1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Event stuff
5 *
6 * Copyright 1995-2002 Bernd Schmidt
7 * Copyright 1995 Alessandro Bissacco
8 * Copyright 2000-2012 Toni Wilen
9 */
10
11 #include "sysconfig.h"
12 #include "sysdeps.h"
13
14 #include "options.h"
15 #include "events.h"
16
17 unsigned long int event_cycles, nextevent, currcycle;
18 int is_syncline, is_syncline_end;
19 long cycles_to_next_event;
20 long max_cycles_to_next_event;
21 long cycles_to_hsync_event;
22 unsigned long start_cycles;
23
24 frame_time_t vsyncmintime, vsyncmaxtime, vsyncwaittime;
25 int vsynctimebase;
26
events_schedule(void)27 void events_schedule (void)
28 {
29 int i;
30
31 unsigned long int mintime = ~0L;
32 for (i = 0; i < ev_max; i++) {
33 if (eventtab[i].active) {
34 unsigned long int eventtime = eventtab[i].evtime - currcycle;
35 if (eventtime < mintime)
36 mintime = eventtime;
37 }
38 }
39 nextevent = currcycle + mintime;
40 }
41
do_cycles_slow(unsigned long cycles_to_add)42 void do_cycles_slow (unsigned long cycles_to_add)
43 {
44 if ((pissoff -= cycles_to_add) >= 0)
45 return;
46
47 cycles_to_add = -pissoff;
48 pissoff = 0;
49
50 while ((nextevent - currcycle) <= cycles_to_add) {
51 int i;
52
53 /* Keep only CPU emulation running while waiting for sync point. */
54 if (is_syncline > 0) {
55 int rpt = read_processor_time ();
56 int v = rpt - vsyncmintime;
57 int v2 = rpt - is_syncline_end;
58 if (v > vsynctimebase || v < -vsynctimebase) {
59 v = 0;
60 }
61 if (v < 0 && v2 < 0) {
62 pissoff = pissoff_value;
63 return;
64 }
65 } else if (is_syncline < 0) {
66 int rpt = read_processor_time ();
67 int v = rpt - is_syncline_end;
68 if (v < 0) {
69 pissoff = pissoff_value;
70 return;
71 }
72 }
73 is_syncline = 0;
74
75 cycles_to_add -= nextevent - currcycle;
76 currcycle = nextevent;
77
78 for (i = 0; i < ev_max; i++) {
79 if (eventtab[i].active && eventtab[i].evtime == currcycle) {
80 (*eventtab[i].handler)();
81 }
82 }
83 events_schedule ();
84
85
86 }
87 currcycle += cycles_to_add;
88 }
89
MISC_handler(void)90 void MISC_handler (void)
91 {
92 static bool dorecheck;
93 bool recheck;
94 int i;
95 evt mintime;
96 evt ct = get_cycles ();
97 static int recursive;
98
99 if (recursive) {
100 dorecheck = true;
101 return;
102 }
103 recursive++;
104 eventtab[ev_misc].active = 0;
105 recheck = true;
106 while (recheck) {
107 recheck = false;
108 mintime = ~0L;
109 for (i = 0; i < ev2_max; i++) {
110 if (eventtab2[i].active) {
111 if (eventtab2[i].evtime == ct) {
112 eventtab2[i].active = false;
113 eventtab2[i].handler (eventtab2[i].data);
114 if (dorecheck || eventtab2[i].active) {
115 recheck = true;
116 dorecheck = false;
117 }
118 } else {
119 evt eventtime = eventtab2[i].evtime - ct;
120 if (eventtime < mintime)
121 mintime = eventtime;
122 }
123 }
124 }
125 }
126 if (mintime != ~0UL) {
127 eventtab[ev_misc].active = true;
128 eventtab[ev_misc].oldcycles = ct;
129 eventtab[ev_misc].evtime = ct + mintime;
130 events_schedule ();
131 }
132 recursive--;
133 }
134
135
event2_newevent_xx(int no,evt t,uae_u32 data,evfunc2 func)136 void event2_newevent_xx (int no, evt t, uae_u32 data, evfunc2 func)
137 {
138 evt et;
139 static int next = ev2_misc;
140
141 et = t + get_cycles ();
142 if (no < 0) {
143 no = next;
144 for (;;) {
145 if (!eventtab2[no].active)
146 break;
147 if (eventtab2[no].evtime == et && eventtab2[no].handler == func && eventtab2[no].data == data)
148 break;
149 no++;
150 if (no == ev2_max)
151 no = ev2_misc;
152 if (no == next) {
153 write_log (_T("out of event2's!\n"));
154 return;
155 }
156 }
157 next = no;
158 }
159 eventtab2[no].active = true;
160 eventtab2[no].evtime = et;
161 eventtab2[no].handler = func;
162 eventtab2[no].data = data;
163 MISC_handler ();
164 }
165
166