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