1 #include "gb.h"
2 #ifdef _WIN32
3 #ifndef _WIN32_WINNT
4 #define _WIN32_WINNT 0x0500
5 #endif
6 #include <windows.h>
7 #else
8 #include <sys/time.h>
9 #endif
10
11 static const unsigned GB_TAC_TRIGGER_BITS[] = {512, 8, 32, 128};
12
13 #ifndef GB_DISABLE_TIMEKEEPING
get_nanoseconds(void)14 static int64_t get_nanoseconds(void)
15 {
16 #ifndef _WIN32
17 struct timeval now;
18 gettimeofday(&now, NULL);
19 return (now.tv_usec) * 1000 + now.tv_sec * 1000000000L;
20 #else
21 FILETIME time;
22 GetSystemTimeAsFileTime(&time);
23 return (((int64_t)time.dwHighDateTime << 32) | time.dwLowDateTime) * 100L;
24 #endif
25 }
26
nsleep(uint64_t nanoseconds)27 static void nsleep(uint64_t nanoseconds)
28 {
29 #ifndef _WIN32
30 struct timespec sleep = {0, nanoseconds};
31 nanosleep(&sleep, NULL);
32 #else
33 HANDLE timer;
34 LARGE_INTEGER time;
35 timer = CreateWaitableTimer(NULL, true, NULL);
36 time.QuadPart = -(nanoseconds / 100L);
37 SetWaitableTimer(timer, &time, 0, NULL, NULL, false);
38 WaitForSingleObject(timer, INFINITE);
39 CloseHandle(timer);
40 #endif
41 }
42
GB_timing_sync_turbo(GB_gameboy_t * gb)43 bool GB_timing_sync_turbo(GB_gameboy_t *gb)
44 {
45 if (!gb->turbo_dont_skip) {
46 int64_t nanoseconds = get_nanoseconds();
47 if (nanoseconds <= gb->last_sync + (1000000000LL * LCDC_PERIOD / GB_get_clock_rate(gb))) {
48 return true;
49 }
50 gb->last_sync = nanoseconds;
51 }
52 return false;
53 }
54
GB_timing_sync(GB_gameboy_t * gb)55 void GB_timing_sync(GB_gameboy_t *gb)
56 {
57 if (gb->turbo) {
58 gb->cycles_since_last_sync = 0;
59 return;
60 }
61 /* Prevent syncing if not enough time has passed.*/
62 if (gb->cycles_since_last_sync < LCDC_PERIOD / 3) return;
63
64 uint64_t target_nanoseconds = gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */
65 int64_t nanoseconds = get_nanoseconds();
66 int64_t time_to_sleep = target_nanoseconds + gb->last_sync - nanoseconds;
67 if (time_to_sleep > 0 && time_to_sleep < LCDC_PERIOD * 1200000000LL / GB_get_clock_rate(gb)) { // +20% to be more forgiving
68 nsleep(time_to_sleep);
69 gb->last_sync += target_nanoseconds;
70 }
71 else {
72 if (time_to_sleep < 0 && -time_to_sleep < LCDC_PERIOD * 1200000000LL / GB_get_clock_rate(gb)) {
73 // We're running a bit too slow, but the difference is small enough,
74 // just skip this sync and let it even out
75 return;
76 }
77 gb->last_sync = nanoseconds;
78 }
79
80 gb->cycles_since_last_sync = 0;
81 if (gb->update_input_hint_callback) {
82 gb->update_input_hint_callback(gb);
83 }
84 }
85 #else
86
GB_timing_sync_turbo(GB_gameboy_t * gb)87 bool GB_timing_sync_turbo(GB_gameboy_t *gb)
88 {
89 return false;
90 }
91
GB_timing_sync(GB_gameboy_t * gb)92 void GB_timing_sync(GB_gameboy_t *gb)
93 {
94 }
95
96 #endif
97
98 #define IR_DECAY 31500
99 #define IR_THRESHOLD 19900
100 #define IR_MAX IR_THRESHOLD * 2 + IR_DECAY
101
GB_ir_run(GB_gameboy_t * gb,uint32_t cycles)102 static void GB_ir_run(GB_gameboy_t *gb, uint32_t cycles)
103 {
104 if (gb->model == GB_MODEL_AGB) return;
105 if (gb->infrared_input || gb->cart_ir || (gb->io_registers[GB_IO_RP] & 1)) {
106 gb->ir_sensor += cycles;
107 if (gb->ir_sensor > IR_MAX) {
108 gb->ir_sensor = IR_MAX;
109 }
110
111 gb->effective_ir_input = gb->ir_sensor >= IR_THRESHOLD && gb->ir_sensor <= IR_THRESHOLD + IR_DECAY;
112 }
113 else {
114 if (gb->ir_sensor <= cycles) {
115 gb->ir_sensor = 0;
116 }
117 else {
118 gb->ir_sensor -= cycles;
119 }
120 gb->effective_ir_input = false;
121 }
122
123 }
124
advance_tima_state_machine(GB_gameboy_t * gb)125 static void advance_tima_state_machine(GB_gameboy_t *gb)
126 {
127 if (gb->tima_reload_state == GB_TIMA_RELOADED) {
128 gb->tima_reload_state = GB_TIMA_RUNNING;
129 }
130 else if (gb->tima_reload_state == GB_TIMA_RELOADING) {
131 gb->io_registers[GB_IO_IF] |= 4;
132 gb->tima_reload_state = GB_TIMA_RELOADED;
133 }
134 }
135
increase_tima(GB_gameboy_t * gb)136 static void increase_tima(GB_gameboy_t *gb)
137 {
138 gb->io_registers[GB_IO_TIMA]++;
139 if (gb->io_registers[GB_IO_TIMA] == 0) {
140 gb->io_registers[GB_IO_TIMA] = gb->io_registers[GB_IO_TMA];
141 gb->tima_reload_state = GB_TIMA_RELOADING;
142 }
143 }
144
GB_set_internal_div_counter(GB_gameboy_t * gb,uint16_t value)145 static void GB_set_internal_div_counter(GB_gameboy_t *gb, uint16_t value)
146 {
147 /* TIMA increases when a specific high-bit becomes a low-bit. */
148 uint16_t triggers = gb->div_counter & ~value;
149 if ((gb->io_registers[GB_IO_TAC] & 4) && (triggers & GB_TAC_TRIGGER_BITS[gb->io_registers[GB_IO_TAC] & 3])) {
150 increase_tima(gb);
151 }
152
153 /* TODO: Can switching to double speed mode trigger an event? */
154 uint16_t apu_bit = gb->cgb_double_speed? 0x2000 : 0x1000;
155 if (triggers & apu_bit) {
156 GB_apu_run(gb);
157 GB_apu_div_event(gb);
158 }
159 else {
160 uint16_t secondary_triggers = ~gb->div_counter & value;
161 if (secondary_triggers & apu_bit) {
162 GB_apu_run(gb);
163 GB_apu_div_secondary_event(gb);
164 }
165 }
166 gb->div_counter = value;
167 }
168
GB_timers_run(GB_gameboy_t * gb,uint8_t cycles)169 static void GB_timers_run(GB_gameboy_t *gb, uint8_t cycles)
170 {
171 if (gb->stopped) {
172 if (GB_is_cgb(gb)) {
173 gb->apu.apu_cycles += 4 << !gb->cgb_double_speed;
174 }
175 return;
176 }
177
178 GB_STATE_MACHINE(gb, div, cycles, 1) {
179 GB_STATE(gb, div, 1);
180 GB_STATE(gb, div, 2);
181 GB_STATE(gb, div, 3);
182 }
183
184 GB_set_internal_div_counter(gb, 0);
185 main:
186 GB_SLEEP(gb, div, 1, 3);
187 while (true) {
188 advance_tima_state_machine(gb);
189 GB_set_internal_div_counter(gb, gb->div_counter + 4);
190 gb->apu.apu_cycles += 4 << !gb->cgb_double_speed;
191 GB_SLEEP(gb, div, 2, 4);
192 }
193
194 /* Todo: This is ugly to allow compatibility with 0.11 save states. Fix me when breaking save compatibility */
195 {
196 div3:
197 /* Compensate for lack of prefetch emulation, as well as DIV's internal initial value */
198 GB_set_internal_div_counter(gb, 8);
199 goto main;
200 }
201 }
202
advance_serial(GB_gameboy_t * gb,uint8_t cycles)203 static void advance_serial(GB_gameboy_t *gb, uint8_t cycles)
204 {
205 if (gb->printer.command_state || gb->printer.bits_received) {
206 gb->printer.idle_time += cycles;
207 }
208 if (gb->serial_length == 0) {
209 gb->serial_cycles += cycles;
210 return;
211 }
212
213 while (cycles > gb->serial_length) {
214 advance_serial(gb, gb->serial_length);
215 cycles -= gb->serial_length;
216 }
217
218 uint16_t previous_serial_cycles = gb->serial_cycles;
219 gb->serial_cycles += cycles;
220 if ((gb->serial_cycles & gb->serial_length) != (previous_serial_cycles & gb->serial_length)) {
221 gb->serial_count++;
222 if (gb->serial_count == 8) {
223 gb->serial_length = 0;
224 gb->serial_count = 0;
225 gb->io_registers[GB_IO_SC] &= ~0x80;
226 gb->io_registers[GB_IO_IF] |= 8;
227 }
228
229 gb->io_registers[GB_IO_SB] <<= 1;
230
231 if (gb->serial_transfer_bit_end_callback) {
232 gb->io_registers[GB_IO_SB] |= gb->serial_transfer_bit_end_callback(gb);
233 }
234 else {
235 gb->io_registers[GB_IO_SB] |= 1;
236 }
237
238 if (gb->serial_length) {
239 /* Still more bits to send */
240 if (gb->serial_transfer_bit_start_callback) {
241 gb->serial_transfer_bit_start_callback(gb, gb->io_registers[GB_IO_SB] & 0x80);
242 }
243 }
244
245 }
246 return;
247
248 }
249
GB_rtc_run(GB_gameboy_t * gb,uint8_t cycles)250 static void GB_rtc_run(GB_gameboy_t *gb, uint8_t cycles)
251 {
252 if (gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc) return;
253 gb->rtc_cycles += cycles;
254 time_t current_time = 0;
255
256 switch (gb->rtc_mode) {
257 case GB_RTC_MODE_SYNC_TO_HOST:
258 // Sync in a 1/32s resolution
259 if (gb->rtc_cycles < GB_get_unmultiplied_clock_rate(gb) / 16) return;
260 gb->rtc_cycles -= GB_get_unmultiplied_clock_rate(gb) / 16;
261 current_time = time(NULL);
262 break;
263 case GB_RTC_MODE_ACCURATE:
264 if (gb->cartridge_type->mbc_type != GB_HUC3 && (gb->rtc_real.high & 0x40)) {
265 gb->rtc_cycles -= cycles;
266 return;
267 }
268 if (gb->rtc_cycles < GB_get_unmultiplied_clock_rate(gb) * 2) return;
269 gb->rtc_cycles -= GB_get_unmultiplied_clock_rate(gb) * 2;
270 current_time = gb->last_rtc_second + 1;
271 break;
272 }
273
274 if (gb->cartridge_type->mbc_type == GB_HUC3) {
275 while (gb->last_rtc_second / 60 < current_time / 60) {
276 gb->last_rtc_second += 60;
277 gb->huc3_minutes++;
278 if (gb->huc3_minutes == 60 * 24) {
279 gb->huc3_days++;
280 gb->huc3_minutes = 0;
281 }
282 }
283 return;
284 }
285 bool running = false;
286 if (gb->cartridge_type->mbc_type == GB_TPP1) {
287 running = gb->tpp1_mr4 & 0x4;
288 }
289 else {
290 running = (gb->rtc_real.high & 0x40) == 0;
291 }
292
293 if (running) { /* is timer running? */
294 while (gb->last_rtc_second + 60 * 60 * 24 < current_time) {
295 gb->last_rtc_second += 60 * 60 * 24;
296 if (gb->cartridge_type->mbc_type == GB_TPP1) {
297 if (++gb->rtc_real.tpp1.weekday == 7) {
298 gb->rtc_real.tpp1.weekday = 0;
299 if (++gb->rtc_real.tpp1.weeks == 0) {
300 gb->tpp1_mr4 |= 8; /* Overflow bit */
301 }
302 }
303 }
304 else if (++gb->rtc_real.days == 0) {
305 if (gb->rtc_real.high & 1) { /* Bit 8 of days*/
306 gb->rtc_real.high |= 0x80; /* Overflow bit */
307 }
308
309 gb->rtc_real.high ^= 1;
310 }
311 }
312
313 while (gb->last_rtc_second < current_time) {
314 gb->last_rtc_second++;
315 if (++gb->rtc_real.seconds != 60) continue;
316 gb->rtc_real.seconds = 0;
317
318 if (++gb->rtc_real.minutes != 60) continue;
319 gb->rtc_real.minutes = 0;
320
321 if (gb->cartridge_type->mbc_type == GB_TPP1) {
322 if (++gb->rtc_real.tpp1.hours != 24) continue;
323 gb->rtc_real.tpp1.hours = 0;
324 if (++gb->rtc_real.tpp1.weekday != 7) continue;
325 gb->rtc_real.tpp1.weekday = 0;
326 if (++gb->rtc_real.tpp1.weeks == 0) {
327 gb->tpp1_mr4 |= 8; /* Overflow bit */
328 }
329 }
330 else {
331 if (++gb->rtc_real.hours != 24) continue;
332 gb->rtc_real.hours = 0;
333
334 if (++gb->rtc_real.days != 0) continue;
335
336 if (gb->rtc_real.high & 1) { /* Bit 8 of days*/
337 gb->rtc_real.high |= 0x80; /* Overflow bit */
338 }
339
340 gb->rtc_real.high ^= 1;
341 }
342 }
343 }
344 }
345
346
GB_advance_cycles(GB_gameboy_t * gb,uint8_t cycles)347 void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
348 {
349 if (gb->speed_switch_countdown) {
350 if (gb->speed_switch_countdown == cycles) {
351 gb->cgb_double_speed ^= true;
352 gb->speed_switch_countdown = 0;
353 }
354 else if (gb->speed_switch_countdown > cycles) {
355 gb->speed_switch_countdown -= cycles;
356 }
357 else {
358 uint8_t old_cycles = gb->speed_switch_countdown;
359 cycles -= old_cycles;
360 gb->speed_switch_countdown = 0;
361 GB_advance_cycles(gb, old_cycles);
362 gb->cgb_double_speed ^= true;
363 }
364 }
365 gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF; // Sort of hacky, but too many cross-component interactions to do it right
366 // Affected by speed boost
367 gb->dma_cycles += cycles;
368
369 GB_timers_run(gb, cycles);
370 if (!gb->stopped) {
371 advance_serial(gb, cycles); // TODO: Verify what happens in STOP mode
372 }
373
374 if (gb->speed_switch_halt_countdown) {
375 gb->speed_switch_halt_countdown -= cycles;
376 if (gb->speed_switch_halt_countdown <= 0) {
377 gb->speed_switch_halt_countdown = 0;
378 gb->halted = false;
379 }
380 }
381
382 gb->debugger_ticks += cycles;
383
384 if (gb->speed_switch_freeze) {
385 if (gb->speed_switch_freeze >= cycles) {
386 gb->speed_switch_freeze -= cycles;
387 return;
388 }
389 cycles -= gb->speed_switch_freeze;
390 gb->speed_switch_freeze = 0;
391 }
392
393 if (!gb->cgb_double_speed) {
394 cycles <<= 1;
395 }
396
397 gb->absolute_debugger_ticks += cycles;
398
399 // Not affected by speed boost
400 if (gb->io_registers[GB_IO_LCDC] & 0x80) {
401 gb->double_speed_alignment += cycles;
402 }
403 gb->hdma_cycles += cycles;
404 gb->apu_output.sample_cycles += cycles;
405 gb->cycles_since_last_sync += cycles;
406 gb->cycles_since_run += cycles;
407
408 gb->rumble_on_cycles += gb->rumble_strength & 3;
409 gb->rumble_off_cycles += (gb->rumble_strength & 3) ^ 3;
410
411 if (!gb->stopped) { // TODO: Verify what happens in STOP mode
412 GB_dma_run(gb);
413 GB_hdma_run(gb);
414 }
415 GB_apu_run(gb);
416 GB_display_run(gb, cycles);
417 GB_ir_run(gb, cycles);
418 GB_rtc_run(gb, cycles);
419 }
420
421 /*
422 This glitch is based on the expected results of mooneye-gb rapid_toggle test.
423 This glitch happens because how TIMA is increased, see GB_set_internal_div_counter.
424 According to GiiBiiAdvance, GBC's behavior is different, but this was not tested or implemented.
425 */
GB_emulate_timer_glitch(GB_gameboy_t * gb,uint8_t old_tac,uint8_t new_tac)426 void GB_emulate_timer_glitch(GB_gameboy_t *gb, uint8_t old_tac, uint8_t new_tac)
427 {
428 /* Glitch only happens when old_tac is enabled. */
429 if (!(old_tac & 4)) return;
430
431 unsigned old_clocks = GB_TAC_TRIGGER_BITS[old_tac & 3];
432 unsigned new_clocks = GB_TAC_TRIGGER_BITS[new_tac & 3];
433
434 /* The bit used for overflow testing must have been 1 */
435 if (gb->div_counter & old_clocks) {
436 /* And now either the timer must be disabled, or the new bit used for overflow testing be 0. */
437 if (!(new_tac & 4) || !(gb->div_counter & new_clocks)) {
438 increase_tima(gb);
439 }
440 }
441 }
442