RTC speed multiplier, for TAS syncing (#422)
This commit is contained in:
parent
a30247cf16
commit
7e5e672988
@ -1854,15 +1854,6 @@ unsigned GB_time_to_alarm(GB_gameboy_t *gb)
|
|||||||
return alarm_time - current_time;
|
return alarm_time - current_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB_set_rtc_mode(GB_gameboy_t *gb, GB_rtc_mode_t mode)
|
|
||||||
{
|
|
||||||
if (gb->rtc_mode != mode) {
|
|
||||||
gb->rtc_mode = mode;
|
|
||||||
gb->rtc_cycles = 0;
|
|
||||||
gb->last_rtc_second = time(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GB_has_accelerometer(GB_gameboy_t *gb)
|
bool GB_has_accelerometer(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
return gb->cartridge_type->mbc_type == GB_MBC7;
|
return gb->cartridge_type->mbc_type == GB_MBC7;
|
||||||
|
@ -247,11 +247,6 @@ typedef enum {
|
|||||||
GB_BOOT_ROM_AGB,
|
GB_BOOT_ROM_AGB,
|
||||||
} GB_boot_rom_t;
|
} GB_boot_rom_t;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GB_RTC_MODE_SYNC_TO_HOST,
|
|
||||||
GB_RTC_MODE_ACCURATE,
|
|
||||||
} GB_rtc_mode_t;
|
|
||||||
|
|
||||||
#ifdef GB_INTERNAL
|
#ifdef GB_INTERNAL
|
||||||
#define LCDC_PERIOD 70224
|
#define LCDC_PERIOD 70224
|
||||||
#define CPU_FREQUENCY 0x400000
|
#define CPU_FREQUENCY 0x400000
|
||||||
@ -640,6 +635,7 @@ struct GB_gameboy_internal_s {
|
|||||||
uint64_t last_sync;
|
uint64_t last_sync;
|
||||||
uint64_t cycles_since_last_sync; // In 8MHz units
|
uint64_t cycles_since_last_sync; // In 8MHz units
|
||||||
GB_rtc_mode_t rtc_mode;
|
GB_rtc_mode_t rtc_mode;
|
||||||
|
uint32_t rtc_second_length;
|
||||||
|
|
||||||
/* Audio */
|
/* Audio */
|
||||||
GB_apu_output_t apu_output;
|
GB_apu_output_t apu_output;
|
||||||
@ -862,9 +858,6 @@ void GB_disconnect_serial(GB_gameboy_t *gb);
|
|||||||
/* For cartridges with an alarm clock */
|
/* For cartridges with an alarm clock */
|
||||||
unsigned GB_time_to_alarm(GB_gameboy_t *gb); // 0 if no alarm
|
unsigned GB_time_to_alarm(GB_gameboy_t *gb); // 0 if no alarm
|
||||||
|
|
||||||
/* RTC emulation mode */
|
|
||||||
void GB_set_rtc_mode(GB_gameboy_t *gb, GB_rtc_mode_t mode);
|
|
||||||
|
|
||||||
/* For cartridges motion controls */
|
/* For cartridges motion controls */
|
||||||
bool GB_has_accelerometer(GB_gameboy_t *gb);
|
bool GB_has_accelerometer(GB_gameboy_t *gb);
|
||||||
// In units of g (gravity's acceleration).
|
// In units of g (gravity's acceleration).
|
||||||
|
@ -248,11 +248,32 @@ static void advance_serial(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB_set_rtc_mode(GB_gameboy_t *gb, GB_rtc_mode_t mode)
|
||||||
|
{
|
||||||
|
if (gb->rtc_mode != mode) {
|
||||||
|
gb->rtc_mode = mode;
|
||||||
|
gb->rtc_cycles = 0;
|
||||||
|
gb->last_rtc_second = time(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GB_set_rtc_multiplier(GB_gameboy_t *gb, double multiplier)
|
||||||
|
{
|
||||||
|
if (multiplier == 1) {
|
||||||
|
gb->rtc_second_length = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gb->rtc_second_length = GB_get_unmultiplied_clock_rate(gb) * 2 * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
{
|
{
|
||||||
if (gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc) return;
|
if (gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc) return;
|
||||||
gb->rtc_cycles += cycles;
|
gb->rtc_cycles += cycles;
|
||||||
time_t current_time = 0;
|
time_t current_time = 0;
|
||||||
|
uint32_t rtc_second_length = unlikely(gb->rtc_second_length)? gb->rtc_second_length : GB_get_unmultiplied_clock_rate(gb) * 2;
|
||||||
|
|
||||||
switch (gb->rtc_mode) {
|
switch (gb->rtc_mode) {
|
||||||
case GB_RTC_MODE_SYNC_TO_HOST:
|
case GB_RTC_MODE_SYNC_TO_HOST:
|
||||||
@ -266,8 +287,8 @@ static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
gb->rtc_cycles -= cycles;
|
gb->rtc_cycles -= cycles;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gb->rtc_cycles < GB_get_unmultiplied_clock_rate(gb) * 2) return;
|
if (gb->rtc_cycles < rtc_second_length) return;
|
||||||
gb->rtc_cycles -= GB_get_unmultiplied_clock_rate(gb) * 2;
|
gb->rtc_cycles -= rtc_second_length;
|
||||||
current_time = gb->last_rtc_second + 1;
|
current_time = gb->last_rtc_second + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,23 @@
|
|||||||
#define timing_h
|
#define timing_h
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GB_RTC_MODE_SYNC_TO_HOST,
|
||||||
|
GB_RTC_MODE_ACCURATE,
|
||||||
|
} GB_rtc_mode_t;
|
||||||
|
|
||||||
|
/* RTC emulation mode */
|
||||||
|
void GB_set_rtc_mode(GB_gameboy_t *gb, GB_rtc_mode_t mode);
|
||||||
|
|
||||||
|
/* Speed multiplier for the RTC, mostly for TAS syncing */
|
||||||
|
void GB_set_rtc_multiplier(GB_gameboy_t *gb, double multiplier);
|
||||||
|
|
||||||
#ifdef GB_INTERNAL
|
#ifdef GB_INTERNAL
|
||||||
internal void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles);
|
internal void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles);
|
||||||
internal void GB_emulate_timer_glitch(GB_gameboy_t *gb, uint8_t old_tac, uint8_t new_tac);
|
internal void GB_emulate_timer_glitch(GB_gameboy_t *gb, uint8_t old_tac, uint8_t new_tac);
|
||||||
internal bool GB_timing_sync_turbo(GB_gameboy_t *gb); /* Returns true if should skip frame */
|
internal bool GB_timing_sync_turbo(GB_gameboy_t *gb); /* Returns true if should skip frame */
|
||||||
internal void GB_timing_sync(GB_gameboy_t *gb);
|
internal void GB_timing_sync(GB_gameboy_t *gb);
|
||||||
internal void GB_set_internal_div_counter(GB_gameboy_t *gb, uint16_t value);
|
internal void GB_set_internal_div_counter(GB_gameboy_t *gb, uint16_t value);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GB_TIMA_RUNNING = 0,
|
GB_TIMA_RUNNING = 0,
|
||||||
GB_TIMA_RELOADING = 1,
|
GB_TIMA_RELOADING = 1,
|
||||||
|
Loading…
Reference in New Issue
Block a user