Increased the remaining sound timer counters and latches to 64-bit;
Applied mainline PCem commit; Intel Flash fixes.
This commit is contained in:
@@ -37,8 +37,6 @@ typedef struct flash_t
|
||||
uint8_t array[131072];
|
||||
} flash_t;
|
||||
|
||||
static flash_t flash;
|
||||
|
||||
char flash_path[1024];
|
||||
|
||||
static uint8_t flash_read(uint32_t addr, void *p)
|
||||
@@ -163,8 +161,7 @@ void *intel_flash_init(uint8_t type)
|
||||
flash_t *flash = malloc(sizeof(flash_t));
|
||||
char fpath[1024];
|
||||
int i;
|
||||
/* IMPORTANT: Do NOT zero the pointers! */
|
||||
memset(flash, 0, sizeof(flash_t) - (6 * sizeof(void *)));
|
||||
memset(flash, 0, sizeof(flash_t));
|
||||
|
||||
// pclog("Initializing Flash (type = %i)\n", type);
|
||||
|
||||
|
13
src/nvr.c
13
src/nvr.c
@@ -104,18 +104,14 @@ void nvr_onesec(void *p)
|
||||
nvr_onesec_cnt++;
|
||||
if (nvr_onesec_cnt >= 100)
|
||||
{
|
||||
nvr_onesec_cnt = 0;
|
||||
|
||||
/* If sync is disabled, move internal clock ahead by 1 second. */
|
||||
if (!(nvrram[RTCREGB] & RTCSET))
|
||||
{
|
||||
nvr_update_status = RTCUIP;
|
||||
if (!enable_sync) rtc_tick();
|
||||
rtc_tick();
|
||||
|
||||
timer_clock();
|
||||
nvr_update_end_count = (int)((244.0 + 1984.0) * TIMER_USEC);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
nvr_onesec_cnt = 0;
|
||||
}
|
||||
nvr_onesec_time += (int)(10000 * TIMER_USEC);
|
||||
}
|
||||
@@ -258,7 +254,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[RTCREGA]=(RTCRS1|RTCRS2);
|
||||
nvrram[RTCREGB]=RTC2412;
|
||||
|
244
src/rtc.c
244
src/rtc.c
@@ -1,6 +1,3 @@
|
||||
/* Copyright holders: Mahod, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
/* Emulation of:
|
||||
Dallas Semiconductor DS12C887 Real Time Clock
|
||||
|
||||
@@ -19,7 +16,7 @@
|
||||
|
||||
int enable_sync;
|
||||
|
||||
typedef struct
|
||||
struct
|
||||
{
|
||||
int sec;
|
||||
int min;
|
||||
@@ -27,16 +24,13 @@ typedef struct
|
||||
int mday;
|
||||
int mon;
|
||||
int year;
|
||||
}
|
||||
internal_clock_t;
|
||||
|
||||
internal_clock_t internal_clock;
|
||||
} internal_clock;
|
||||
|
||||
/* When the RTC was last updated */
|
||||
time_t rtc_set_time = 0;
|
||||
static time_t rtc_set_time = 0;
|
||||
|
||||
/* Table for days in each month */
|
||||
int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
static int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
/* Called to determine whether the year is leap or not */
|
||||
static int rtc_is_leap(int org_year)
|
||||
@@ -51,13 +45,9 @@ static int rtc_is_leap(int org_year)
|
||||
static int rtc_get_days(int org_month, int org_year)
|
||||
{
|
||||
if (org_month != 2)
|
||||
{
|
||||
return rtc_days_in_month[org_month];
|
||||
}
|
||||
else
|
||||
{
|
||||
return rtc_is_leap(org_year) ? 29 : 28;
|
||||
}
|
||||
}
|
||||
|
||||
/* Called when the internal clock gets updated */
|
||||
@@ -104,59 +94,36 @@ void time_update(char *nvrram, int reg)
|
||||
|
||||
switch(reg)
|
||||
{
|
||||
case RTCSECONDS:
|
||||
internal_clock.sec = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCSECONDS] : DCB(nvrram[RTCSECONDS]);
|
||||
break;
|
||||
case RTCMINUTES:
|
||||
internal_clock.min = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMINUTES] : DCB(nvrram[RTCMINUTES]);
|
||||
break;
|
||||
case RTCHOURS:
|
||||
temp = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCHOURS] : DCB(nvrram[RTCHOURS]);
|
||||
case RTC_SECONDS:
|
||||
internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]);
|
||||
break;
|
||||
case RTC_MINUTES:
|
||||
internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]);
|
||||
break;
|
||||
case RTC_HOURS:
|
||||
temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]);
|
||||
|
||||
if (nvrram[RTCREGB] & RTC2412)
|
||||
{
|
||||
internal_clock.hour = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_clock.hour = ((temp & ~RTCAMPM) % 12) + ((temp & RTCAMPM) ? 12 : 0);
|
||||
}
|
||||
break;
|
||||
case RTCDOM:
|
||||
internal_clock.mday = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCDOM] : DCB(nvrram[RTCDOM]);
|
||||
break;
|
||||
case RTCMONTH:
|
||||
internal_clock.mon = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMONTH] : DCB(nvrram[RTCMONTH]);
|
||||
break;
|
||||
case RTCYEAR:
|
||||
internal_clock.year = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCYEAR] : DCB(nvrram[RTCYEAR]);
|
||||
internal_clock.year += (nvrram[RTCREGB] & RTCDM) ? 1900 : (DCB(nvrram[RTCCENTURY]) * 100);
|
||||
break;
|
||||
case RTCCENTURY:
|
||||
if (nvrram[RTCREGB] & RTCDM) return;
|
||||
internal_clock.year %= 100;
|
||||
internal_clock.year += (DCB(nvrram[RTCCENTURY]) * 100);
|
||||
break;
|
||||
case 0xFF: /* Load the entire internal clock state from the NVR. */
|
||||
internal_clock.sec = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCSECONDS] : DCB(nvrram[RTCSECONDS]);
|
||||
internal_clock.min = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMINUTES] : DCB(nvrram[RTCMINUTES]);
|
||||
|
||||
temp = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCHOURS] : DCB(nvrram[RTCHOURS]);
|
||||
|
||||
if (nvrram[RTCREGB] & RTC2412)
|
||||
{
|
||||
internal_clock.hour = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_clock.hour = ((temp & ~RTCAMPM) % 12) + ((temp & RTCAMPM) ? 12 : 0);
|
||||
}
|
||||
|
||||
internal_clock.mday = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCDOM] : DCB(nvrram[RTCDOM]);
|
||||
internal_clock.mon = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCMONTH] : DCB(nvrram[RTCMONTH]);
|
||||
internal_clock.year = (nvrram[RTCREGB] & RTCDM) ? nvrram[RTCYEAR] : DCB(nvrram[RTCYEAR]);
|
||||
internal_clock.year += (nvrram[RTCREGB] & RTCDM) ? 1900 : (DCB(nvrram[RTCCENTURY]) * 100);
|
||||
break;
|
||||
if (nvrram[RTC_REGB] & RTC_2412)
|
||||
internal_clock.hour = temp;
|
||||
else
|
||||
internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0);
|
||||
break;
|
||||
case RTC_DOM:
|
||||
internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]);
|
||||
break;
|
||||
case RTC_MONTH:
|
||||
internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]);
|
||||
break;
|
||||
case RTC_YEAR:
|
||||
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;
|
||||
case RTC_CENTURY:
|
||||
if (nvrram[RTC_REGB] & RTC_DM)
|
||||
return;
|
||||
internal_clock.year %= 100;
|
||||
internal_clock.year += (DCB(nvrram[RTC_CENTURY]) * 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,91 +141,112 @@ 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;
|
||||
}
|
||||
|
||||
time_t cur_time;
|
||||
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)
|
||||
if (nvrram[RTC_REGB] & RTC_DM)
|
||||
{
|
||||
time(&cur_time);
|
||||
nvrram[RTC_SECONDS] = cur_time_tm->tm_sec;
|
||||
nvrram[RTC_MINUTES] = cur_time_tm->tm_min;
|
||||
nvrram[RTC_DOW] = cur_time_tm->tm_wday + 1;
|
||||
nvrram[RTC_DOM] = cur_time_tm->tm_mday;
|
||||
nvrram[RTC_MONTH] = cur_time_tm->tm_mon + 1;
|
||||
nvrram[RTC_YEAR] = cur_time_tm->tm_year % 100;
|
||||
|
||||
/* 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[RTCREGB] & RTCDM)
|
||||
{
|
||||
nvrram[RTCSECONDS] = cur_time_tm->tm_sec;
|
||||
nvrram[RTCMINUTES] = cur_time_tm->tm_min;
|
||||
nvrram[RTCDOW] = cur_time_tm->tm_wday + 1;
|
||||
nvrram[RTCDOM] = cur_time_tm->tm_mday;
|
||||
nvrram[RTCMONTH] = cur_time_tm->tm_mon + 1;
|
||||
nvrram[RTCYEAR] = cur_time_tm->tm_year % 100;
|
||||
|
||||
if (nvrram[RTCREGB] & RTC2412)
|
||||
if (nvrram[RTC_REGB] & RTC_2412)
|
||||
{
|
||||
nvrram[RTCHOURS] = cur_time_tm->tm_hour;
|
||||
nvrram[RTC_HOURS] = cur_time_tm->tm_hour;
|
||||
}
|
||||
else
|
||||
{
|
||||
nvrram[RTCHOURS] = (cur_time_tm->tm_hour % 12) ? (cur_time_tm->tm_hour % 12) : 12;
|
||||
nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? (cur_time_tm->tm_hour % 12) : 12;
|
||||
if (cur_time_tm->tm_hour > 11)
|
||||
{
|
||||
nvrram[RTCHOURS] |= RTCAMPM;
|
||||
}
|
||||
nvrram[RTC_HOURS] |= RTC_AMPM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nvrram[RTCSECONDS] = BCD(cur_time_tm->tm_sec);
|
||||
nvrram[RTCMINUTES] = BCD(cur_time_tm->tm_min);
|
||||
nvrram[RTCDOW] = BCD(cur_time_tm->tm_wday + 1);
|
||||
nvrram[RTCDOM] = BCD(cur_time_tm->tm_mday);
|
||||
nvrram[RTCMONTH] = BCD(cur_time_tm->tm_mon + 1);
|
||||
nvrram[RTCYEAR] = BCD(cur_time_tm->tm_year % 100);
|
||||
nvrram[RTC_SECONDS] = BCD(cur_time_tm->tm_sec);
|
||||
nvrram[RTC_MINUTES] = BCD(cur_time_tm->tm_min);
|
||||
nvrram[RTC_DOW] = BCD(cur_time_tm->tm_wday + 1);
|
||||
nvrram[RTC_DOM] = BCD(cur_time_tm->tm_mday);
|
||||
nvrram[RTC_MONTH] = BCD(cur_time_tm->tm_mon + 1);
|
||||
nvrram[RTC_YEAR] = BCD(cur_time_tm->tm_year % 100);
|
||||
|
||||
if (nvrram[RTCREGB] & RTC2412)
|
||||
if (nvrram[RTC_REGB] & RTC_2412)
|
||||
{
|
||||
nvrram[RTCHOURS] = BCD(cur_time_tm->tm_hour);
|
||||
nvrram[RTC_HOURS] = BCD(cur_time_tm->tm_hour);
|
||||
}
|
||||
else
|
||||
{
|
||||
nvrram[RTCHOURS] = (cur_time_tm->tm_hour % 12) ? BCD(cur_time_tm->tm_hour % 12) : BCD(12);
|
||||
nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? BCD(cur_time_tm->tm_hour % 12) : BCD(12);
|
||||
if (cur_time_tm->tm_hour > 11)
|
||||
{
|
||||
nvrram[RTCHOURS] |= RTCAMPM;
|
||||
}
|
||||
nvrram[RTC_HOURS] |= RTC_AMPM;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
97
src/rtc.h
97
src/rtc.h
@@ -1,36 +1,33 @@
|
||||
/* Copyright holders: Mahod, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define BCD(X) (((X) % 10) | (((X) / 10) << 4))
|
||||
#define DCB(X) ((((X) & 0xF0) >> 4) * 10 + ((X) & 0x0F))
|
||||
|
||||
enum RTCADDR
|
||||
enum RTC_ADDR
|
||||
{
|
||||
RTCSECONDS,
|
||||
RTCALARMSECONDS,
|
||||
RTCMINUTES,
|
||||
RTCALARMMINUTES,
|
||||
RTCHOURS,
|
||||
RTCALARMHOURS,
|
||||
RTCDOW,
|
||||
RTCDOM,
|
||||
RTCMONTH,
|
||||
RTCYEAR,
|
||||
RTCREGA,
|
||||
RTCREGB,
|
||||
RTCREGC,
|
||||
RTCREGD
|
||||
RTC_SECONDS,
|
||||
RTC_ALARMSECONDS,
|
||||
RTC_MINUTES,
|
||||
RTC_ALARMMINUTES,
|
||||
RTC_HOURS,
|
||||
RTC_ALARMHOURS,
|
||||
RTC_DOW,
|
||||
RTC_DOM,
|
||||
RTC_MONTH,
|
||||
RTC_YEAR,
|
||||
RTC_REGA,
|
||||
RTC_REGB,
|
||||
RTC_REGC,
|
||||
RTC_REGD
|
||||
};
|
||||
|
||||
/* The century register at location 32h is a BCD register designed to automatically load the BCD value 20 as the year register changes from 99 to 00.
|
||||
The MSB of this register is not affected when the load of 20 occurs, and remains at the value written by the user. */
|
||||
#define RTCCENTURY 0x32
|
||||
#define RTC_CENTURY 0x32
|
||||
|
||||
/* When the 12-hour format is selected, the higher-order bit of the hours byte represents PM when it is logic 1. */
|
||||
#define RTCAMPM 0b10000000
|
||||
#define RTC_AMPM 0b10000000
|
||||
|
||||
/* Register A bitflags */
|
||||
enum RTCRABITS
|
||||
enum RTC_RA_BITS
|
||||
{
|
||||
/* Rate Selector (RS0)
|
||||
|
||||
@@ -44,19 +41,14 @@ enum RTCRABITS
|
||||
|
||||
Table 3 lists the periodic interrupt rates and the square wave frequencies that can be chosen with the RS bits.
|
||||
These four read/write bits are not affected by !RESET. */
|
||||
RTCRS0 = 0b1,
|
||||
RTCRS1 = 0b10, /*!<RS1*/
|
||||
RTCRS2 = 0b100, /*!<RS2*/
|
||||
RTCRS3 = 0b1000, /*!<RS3*/
|
||||
RTC_RS = 0b1111,
|
||||
/* DV0
|
||||
|
||||
These three bits are used to turn the oscillator on or off and to reset the countdown chain.
|
||||
A pattern of 010 is the only combination of bits that turn the oscillator on and allow the RTC to keep time.
|
||||
A pattern of 11x enables the oscillator but holds the countdown chain in reset.
|
||||
The next update occurs at 500ms after a pattern of 010 is written to DV0, DV1, and DV2. */
|
||||
RTCDV0 = 0b10000,
|
||||
RTCDV1 = 0b100000, /*!<DV1*/
|
||||
RTCDV2 = 0b1000000, /*!<DV2*/
|
||||
RTC_DV0 = 0b1110000,
|
||||
/* Update-In-Progress (UIP)
|
||||
|
||||
This bit is a status flag that can be monitored. When the UIP bit is a 1, the update transfer occurs soon.
|
||||
@@ -64,11 +56,11 @@ enum RTCRABITS
|
||||
The time, calendar, and alarm information in RAM is fully available for access when the UIP bit is 0.
|
||||
The UIP bit is read-only and is not affected by !RESET.
|
||||
Writing the SET bit in Register B to a 1 inhibits any update transfer and clears the UIP status bit. */
|
||||
RTCUIP = 0b10000000
|
||||
RTC_UIP = 0b10000000
|
||||
};
|
||||
|
||||
/* Register B bitflags */
|
||||
enum RTCRBBITS
|
||||
enum RTC_RB_BITS
|
||||
{
|
||||
/* Daylight Saving Enable (DSE)
|
||||
|
||||
@@ -78,79 +70,76 @@ enum RTCRBBITS
|
||||
When DSE is enabled, the internal logic test for the first/last Sunday condition at midnight.
|
||||
If the DSE bit is not set when the test occurs, the daylight saving function does not operate correctly.
|
||||
These adjustments do not occur when the DSE bit is 0. This bit is not affected by internal functions or !RESET. */
|
||||
RTCDSE = 0b1,
|
||||
RTC_DSE = 0b1,
|
||||
/* 24/12
|
||||
|
||||
The 24/12 control bit establishes the format of the hours byte. A 1 indicates the 24-hour mode and a 0 indicates the 12-hour mode.
|
||||
This bit is read/write and is not affected by internal functions or !RESET. */
|
||||
RTC2412 = 0b10,
|
||||
RTC_2412 = 0b10,
|
||||
/* Data Mode (DM)
|
||||
|
||||
This bit indicates whether time and calendar information is in binary or BCD format.
|
||||
The DM bit is set by the program to the appropriate format and can be read as required.
|
||||
This bit is not modified by internal functions or !RESET. A 1 in DM signifies binary data, while a 0 in DM specifies BCD data. */
|
||||
RTCDM = 0b100,
|
||||
RTC_DM = 0b100,
|
||||
/* Square-Wave Enable (SQWE)
|
||||
|
||||
When this bit is set to 1, a square-wave signal at the frequency set by the rate-selection bits RS3-RS0 is driven out on the SQW pin.
|
||||
When the SQWE bit is set to 0, the SQW pin is held low. SQWE is a read/write bit and is cleared by !RESET.
|
||||
SQWE is low if disabled, and is high impedance when VCC is below VPF. SQWE is cleared to 0 on !RESET. */
|
||||
RTCSQWE = 0b1000,
|
||||
RTC_SQWE = 0b1000,
|
||||
/* Update-Ended Interrupt Enable (UIE)
|
||||
|
||||
This bit is a read/write bit that enables the update-end flag (UF) bit in Register C to assert !IRQ.
|
||||
The !RESET pin going low or the SET bit going high clears the UIE bit.
|
||||
The internal functions of the device do not affect the UIE bit, but is cleared to 0 on !RESET. */
|
||||
RTCUIE = 0b10000,
|
||||
RTC_UIE = 0b10000,
|
||||
/* Alarm Interrupt Enable (AIE)
|
||||
|
||||
This bit is a read/write bit that, when set to 1, permits the alarm flag (AF) bit in Register C to assert !IRQ.
|
||||
An alarm interrupt occurs for each second that the three time bytes equal the three alarm bytes, including a don't-care alarm code of binary 11XXXXXX.
|
||||
The AF bit does not initiate the !IRQ signal when the AIE bit is set to 0.
|
||||
The internal functions of the device do not affect the AIE bit, but is cleared to 0 on !RESET. */
|
||||
RTCAIE = 0b100000,
|
||||
RTC_AIE = 0b100000,
|
||||
/* Periodic Interrupt Enable (PIE)
|
||||
|
||||
The PIE bit is a read/write bit that allows the periodic interrupt flag (PF) bit in Register C to drive the !IRQ pin low.
|
||||
When the PIE bit is set to 1, periodic interrupts are generated by driving the !IRQ pin low at a rate specified by the RS3-RS0 bits of Register A.
|
||||
A 0 in the PIE bit blocks the !IRQ output from being driven by a periodic interrupt, but the PF bit is still set at the periodic rate.
|
||||
PIE is not modified by any internal device functions, but is cleared to 0 on !RESET. */
|
||||
RTCPIE = 0b1000000,
|
||||
RTC_PIE = 0b1000000,
|
||||
/* SET
|
||||
|
||||
When the SET bit is 0, the update transfer functions normally by advancing the counts once per second.
|
||||
When the SET bit is written to 1, any update transfer is inhibited, and the program can initialize the time and calendar bytes without an update
|
||||
occurring in the midst of initializing. Read cycles can be executed in a similar manner. SET is a read/write bit and is not affected by !RESET or
|
||||
internal functions of the device. */
|
||||
RTCSET = 0b10000000
|
||||
RTC_SET = 0b10000000
|
||||
};
|
||||
|
||||
/* Register C bitflags */
|
||||
enum RTCRCBITS
|
||||
enum RTC_RC_BITS
|
||||
{
|
||||
/* Unused
|
||||
|
||||
These bits are unused in Register C. These bits always read 0 and cannot be written. */
|
||||
RTCRC0 = 0b1,
|
||||
RTCRC1 = 0b10, /*!<Unused*/
|
||||
RTCRC2 = 0b100, /*!<Unused*/
|
||||
RTCRC3 = 0b1000, /*!<Unused*/
|
||||
RTC_RC = 0b1111,
|
||||
/* Update-Ended Interrupt Flag (UF)
|
||||
|
||||
This bit is set after each update cycle. When the UIE bit is set to 1, the 1 in UF causes the IRQF bit to be a 1, which asserts the !IRQ pin.
|
||||
This bit can be cleared by reading Register C or with a !RESET. */
|
||||
RTCUF = 0b10000,
|
||||
RTC_UF = 0b10000,
|
||||
/* Alarm Interrupt Flag (AF)
|
||||
|
||||
A 1 in the AF bit indicates that the current time has matched the alarm time.
|
||||
If the AIE bit is also 1, the !IRQ pin goes low and a 1 appears in the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */
|
||||
RTCAF = 0b100000,
|
||||
RTC_AF = 0b100000,
|
||||
/* Periodic Interrupt Flag (PF)
|
||||
|
||||
This bit is read-only and is set to 1 when an edge is detected on the selected tap of the divider chain.
|
||||
The RS3 through RS0 bits establish the periodic rate. PF is set to 1 independent of the state of the PIE bit.
|
||||
When both PF and PIE are 1s, the !IRQ signal is active and sets the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */
|
||||
RTCPF = 0b1000000,
|
||||
RTC_PF = 0b1000000,
|
||||
/* Interrupt Request Flag (IRQF)
|
||||
|
||||
The interrupt request flag (IRQF) is set to a 1 when one or more of the following are true:
|
||||
@@ -160,30 +149,26 @@ enum RTCRCBITS
|
||||
|
||||
Any time the IRQF bit is a 1, the !IRQ pin is driven low.
|
||||
All flag bits are cleared after Register C is read by the program or when the !RESET pin is low. */
|
||||
RTCIRQF = 0b10000000
|
||||
RTC_IRQF = 0b10000000
|
||||
};
|
||||
|
||||
/* Register D bitflags */
|
||||
enum RTCRDBITS
|
||||
enum RTC_RD_BITS
|
||||
{
|
||||
/* Unused
|
||||
|
||||
The remaining bits of Register D are not usable. They cannot be written and they always read 0. */
|
||||
RTCRD0 = 0b1,
|
||||
RTCRD1 = 0b10, /*!<Unused*/
|
||||
RTCRD2 = 0b100, /*!<Unused*/
|
||||
RTCRD3 = 0b1000, /*!<Unused*/
|
||||
RTCRD4 = 0b10000, /*!<Unused*/
|
||||
RTCRD5 = 0b100000, /*!<Unused*/
|
||||
RTCRD6 = 0b1000000, /*!<Unused*/
|
||||
RTC_RD = 0b1111111,
|
||||
/* Valid RAM and Time (VRT)
|
||||
|
||||
This bit indicates the condition of the battery connected to the VBAT pin. This bit is not writeable and should always be 1 when read.
|
||||
If a 0 is ever present, an exhausted internal lithium energy source is indicated and both the contents of the RTC data and RAM data are questionable.
|
||||
This bit is unaffected by !RESET. */
|
||||
RTCVRT = 0b10000000
|
||||
RTC_VRT = 0b10000000
|
||||
};
|
||||
|
||||
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);
|
||||
|
@@ -43,12 +43,12 @@ typedef struct adgold_t
|
||||
|
||||
struct
|
||||
{
|
||||
int timer0_latch, timer0_count;
|
||||
int timerbase_latch, timerbase_count;
|
||||
int timer1_latch, timer1_count;
|
||||
int timer2_latch, timer2_count, timer2_read;
|
||||
int64_t timer0_latch, timer0_count;
|
||||
int64_t timerbase_latch, timerbase_count;
|
||||
int64_t timer1_latch, timer1_count;
|
||||
int64_t timer2_latch, timer2_count, timer2_read;
|
||||
|
||||
int voice_count[2], voice_latch[2];
|
||||
int64_t voice_count[2], voice_latch[2];
|
||||
} adgold_mma;
|
||||
|
||||
opl_t opl;
|
||||
|
@@ -50,7 +50,7 @@ typedef struct sb_dsp_t
|
||||
|
||||
int64_t sbcount, sb_count_i;
|
||||
|
||||
int sblatcho, sblatchi;
|
||||
int64_t sblatcho, sblatchi;
|
||||
|
||||
uint16_t sb_addr;
|
||||
|
||||
|
@@ -16,7 +16,7 @@ extern int sn76489_mute;
|
||||
typedef struct sn76489_t
|
||||
{
|
||||
int stat[4];
|
||||
int latch[4], count[4];
|
||||
int64_t latch[4], count[4];
|
||||
int freqlo[4], freqhi[4];
|
||||
int vol[4];
|
||||
uint32_t shift;
|
||||
|
Reference in New Issue
Block a user