Rewrote handling of host time synchronisation. Amstrad machines now boot again.
Also fixed a bug where the emulated time ran 100x faster than expected.
This commit is contained in:
parent
535604b760
commit
4e299a8038
3 changed files with 69 additions and 57 deletions
10
src/nvr.c
10
src/nvr.c
|
|
@ -103,12 +103,11 @@ void nvr_onesec(void *p)
|
|||
if (!(nvrram[RTC_REGB] & RTC_SET))
|
||||
{
|
||||
nvr_update_status = RTC_UIP;
|
||||
/* If sync is disabled, move internal clock ahead by 1 second. */
|
||||
if (!enable_sync)
|
||||
rtc_tick();
|
||||
rtc_tick();
|
||||
|
||||
nvr_update_end_count = (int)((244.0 + 1984.0) * TIMER_USEC);
|
||||
}
|
||||
nvr_onesec_cnt = 0;
|
||||
}
|
||||
nvr_onesec_time += (int)(10000 * TIMER_USEC);
|
||||
}
|
||||
|
|
@ -241,7 +240,10 @@ void loadnvr()
|
|||
return;
|
||||
}
|
||||
fread(nvrram,128,1,f);
|
||||
if (!enable_sync) time_update(nvrram, 0xFF); /* Update the internal clock state based on the NVR registers. */
|
||||
if (enable_sync)
|
||||
time_internal_sync(nvrram);
|
||||
else
|
||||
time_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */
|
||||
fclose(f);
|
||||
nvrram[RTC_REGA] = 6;
|
||||
nvrram[RTC_REGB] = RTC_2412;
|
||||
|
|
|
|||
114
src/rtc.c
114
src/rtc.c
|
|
@ -124,22 +124,6 @@ void time_update(char *nvrram, int reg)
|
|||
internal_clock.year %= 100;
|
||||
internal_clock.year += (DCB(nvrram[RTC_CENTURY]) * 100);
|
||||
break;
|
||||
case 0xFF: /* Load the entire internal clock state from the NVR. */
|
||||
internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]);
|
||||
internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]);
|
||||
|
||||
temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]);
|
||||
|
||||
if (nvrram[RTC_REGB] & RTC_2412)
|
||||
internal_clock.hour = temp;
|
||||
else
|
||||
internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0);
|
||||
|
||||
internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]);
|
||||
internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]);
|
||||
internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]);
|
||||
internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,50 +141,31 @@ static int time_week_day()
|
|||
}
|
||||
|
||||
/* Called to get time into the internal clock */
|
||||
static void time_internal(struct tm **time_var)
|
||||
static void time_internal_get(struct tm *time_var)
|
||||
{
|
||||
if (*time_var == NULL)
|
||||
*time_var = (struct tm *)malloc(sizeof(struct tm));
|
||||
|
||||
(*time_var)->tm_sec = internal_clock.sec;
|
||||
(*time_var)->tm_min = internal_clock.min;
|
||||
(*time_var)->tm_hour = internal_clock.hour;
|
||||
(*time_var)->tm_wday = time_week_day();
|
||||
(*time_var)->tm_mday = internal_clock.mday;
|
||||
(*time_var)->tm_mon = internal_clock.mon - 1;
|
||||
(*time_var)->tm_year = internal_clock.year - 1900;
|
||||
time_var->tm_sec = internal_clock.sec;
|
||||
time_var->tm_min = internal_clock.min;
|
||||
time_var->tm_hour = internal_clock.hour;
|
||||
time_var->tm_wday = time_week_day();
|
||||
time_var->tm_mday = internal_clock.mday;
|
||||
time_var->tm_mon = internal_clock.mon - 1;
|
||||
time_var->tm_year = internal_clock.year - 1900;
|
||||
}
|
||||
|
||||
static time_t cur_time;
|
||||
static struct tm *cur_time_tm;
|
||||
static void time_internal_set(struct tm *time_var)
|
||||
{
|
||||
internal_clock.sec = time_var->tm_sec;
|
||||
internal_clock.min = time_var->tm_min;
|
||||
internal_clock.hour = time_var->tm_hour;
|
||||
internal_clock.mday = time_var->tm_mday;
|
||||
internal_clock.mon = time_var->tm_mon + 1;
|
||||
internal_clock.year = time_var->tm_year + 1900;
|
||||
}
|
||||
|
||||
/* Periodic RTC update function
|
||||
See also: nvr_onesec() in nvr.c
|
||||
*/
|
||||
void time_get(char *nvrram)
|
||||
static void time_set_nvrram(char *nvrram, struct tm *cur_time_tm)
|
||||
{
|
||||
int dow, mon, year;
|
||||
|
||||
if (enable_sync)
|
||||
{
|
||||
time(&cur_time);
|
||||
|
||||
/* Mingw doesn't support localtime_r */
|
||||
#if __MINGW32__
|
||||
cur_time_tm = localtime(&cur_time);
|
||||
#else
|
||||
#if __MINGW64__
|
||||
cur_time_tm = localtime(&cur_time);
|
||||
#else
|
||||
localtime_r(&cur_time, &cur_time_tm);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
time_internal(&cur_time_tm);
|
||||
}
|
||||
|
||||
if (nvrram[RTC_REGB] & RTC_DM)
|
||||
{
|
||||
nvrram[RTC_SECONDS] = cur_time_tm->tm_sec;
|
||||
|
|
@ -242,3 +207,46 @@ void time_get(char *nvrram)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void time_internal_set_nvrram(char *nvrram)
|
||||
{
|
||||
int temp;
|
||||
|
||||
/* Load the entire internal clock state from the NVR. */
|
||||
internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]);
|
||||
internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]);
|
||||
|
||||
temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]);
|
||||
|
||||
if (nvrram[RTC_REGB] & RTC_2412)
|
||||
internal_clock.hour = temp;
|
||||
else
|
||||
internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0);
|
||||
|
||||
internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]);
|
||||
internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]);
|
||||
internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]);
|
||||
internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100);
|
||||
}
|
||||
|
||||
void time_internal_sync(char *nvrram)
|
||||
{
|
||||
struct tm *cur_time_tm;
|
||||
time_t cur_time;
|
||||
|
||||
time(&cur_time);
|
||||
cur_time_tm = localtime(&cur_time);
|
||||
|
||||
time_internal_set(cur_time_tm);
|
||||
|
||||
time_set_nvrram(nvrram, cur_time_tm);
|
||||
}
|
||||
|
||||
void time_get(char *nvrram)
|
||||
{
|
||||
struct tm cur_time_tm;
|
||||
|
||||
time_internal_get(&cur_time_tm);
|
||||
|
||||
time_set_nvrram(nvrram, &cur_time_tm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,3 +170,5 @@ enum RTC_RD_BITS
|
|||
void rtc_tick();
|
||||
void time_update(char *nvrram, int reg);
|
||||
void time_get(char *nvrram);
|
||||
void time_internal_set_nvrram(char *nvrram);
|
||||
void time_internal_sync(char *nvrram);
|
||||
|
|
|
|||
Loading…
Reference in a new issue