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