Combine multiple BCD implementations.
Signed-off-by: Paul Brook <paul@codesourcery.com>
} M48t59SysBusState;
/* Fake timer functions */
-/* Generic helpers for BCD */
-static inline uint8_t toBCD (uint8_t value)
-{
- return (((value / 10) % 10) << 4) | (value % 10);
-}
-
-static inline uint8_t fromBCD (uint8_t BCD)
-{
- return ((BCD >> 4) * 10) + (BCD & 0x0F);
-}
/* Alarm management */
static void alarm_cb (void *opaque)
break;
case 0x1FF2:
/* alarm seconds */
- tmp = fromBCD(val & 0x7F);
+ tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
NVRAM->alarm.tm_sec = tmp;
NVRAM->buffer[0x1FF2] = val;
break;
case 0x1FF3:
/* alarm minutes */
- tmp = fromBCD(val & 0x7F);
+ tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
NVRAM->alarm.tm_min = tmp;
NVRAM->buffer[0x1FF3] = val;
break;
case 0x1FF4:
/* alarm hours */
- tmp = fromBCD(val & 0x3F);
+ tmp = from_bcd(val & 0x3F);
if (tmp >= 0 && tmp <= 23) {
NVRAM->alarm.tm_hour = tmp;
NVRAM->buffer[0x1FF4] = val;
break;
case 0x1FF5:
/* alarm date */
- tmp = fromBCD(val & 0x1F);
+ tmp = from_bcd(val & 0x1F);
if (tmp != 0) {
NVRAM->alarm.tm_mday = tmp;
NVRAM->buffer[0x1FF5] = val;
case 0x1FF9:
case 0x07F9:
/* seconds (BCD) */
- tmp = fromBCD(val & 0x7F);
+ tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
get_time(NVRAM, &tm);
tm.tm_sec = tmp;
case 0x1FFA:
case 0x07FA:
/* minutes (BCD) */
- tmp = fromBCD(val & 0x7F);
+ tmp = from_bcd(val & 0x7F);
if (tmp >= 0 && tmp <= 59) {
get_time(NVRAM, &tm);
tm.tm_min = tmp;
case 0x1FFB:
case 0x07FB:
/* hours (BCD) */
- tmp = fromBCD(val & 0x3F);
+ tmp = from_bcd(val & 0x3F);
if (tmp >= 0 && tmp <= 23) {
get_time(NVRAM, &tm);
tm.tm_hour = tmp;
case 0x1FFC:
case 0x07FC:
/* day of the week / century */
- tmp = fromBCD(val & 0x07);
+ tmp = from_bcd(val & 0x07);
get_time(NVRAM, &tm);
tm.tm_wday = tmp;
set_time(NVRAM, &tm);
case 0x1FFD:
case 0x07FD:
/* date */
- tmp = fromBCD(val & 0x1F);
+ tmp = from_bcd(val & 0x1F);
if (tmp != 0) {
get_time(NVRAM, &tm);
tm.tm_mday = tmp;
case 0x1FFE:
case 0x07FE:
/* month */
- tmp = fromBCD(val & 0x1F);
+ tmp = from_bcd(val & 0x1F);
if (tmp >= 1 && tmp <= 12) {
get_time(NVRAM, &tm);
tm.tm_mon = tmp - 1;
case 0x1FFF:
case 0x07FF:
/* year */
- tmp = fromBCD(val);
+ tmp = from_bcd(val);
if (tmp >= 0 && tmp <= 99) {
get_time(NVRAM, &tm);
if (NVRAM->type == 8)
- tm.tm_year = fromBCD(val) + 68; // Base year is 1968
+ tm.tm_year = from_bcd(val) + 68; // Base year is 1968
else
- tm.tm_year = fromBCD(val);
+ tm.tm_year = from_bcd(val);
set_time(NVRAM, &tm);
}
break;
case 0x07F9:
/* seconds (BCD) */
get_time(NVRAM, &tm);
- retval = (NVRAM->buffer[addr] & 0x80) | toBCD(tm.tm_sec);
+ retval = (NVRAM->buffer[addr] & 0x80) | to_bcd(tm.tm_sec);
break;
case 0x1FFA:
case 0x07FA:
/* minutes (BCD) */
get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_min);
+ retval = to_bcd(tm.tm_min);
break;
case 0x1FFB:
case 0x07FB:
/* hours (BCD) */
get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_hour);
+ retval = to_bcd(tm.tm_hour);
break;
case 0x1FFC:
case 0x07FC:
case 0x07FD:
/* date */
get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mday);
+ retval = to_bcd(tm.tm_mday);
break;
case 0x1FFE:
case 0x07FE:
/* month */
get_time(NVRAM, &tm);
- retval = toBCD(tm.tm_mon + 1);
+ retval = to_bcd(tm.tm_mon + 1);
break;
case 0x1FFF:
case 0x07FF:
/* year */
get_time(NVRAM, &tm);
if (NVRAM->type == 8)
- retval = toBCD(tm.tm_year - 68); // Base year is 1968
+ retval = to_bcd(tm.tm_year - 68); // Base year is 1968
else
- retval = toBCD(tm.tm_year);
+ retval = to_bcd(tm.tm_year);
break;
default:
/* Check lock registers state */
}
}
-static inline int to_bcd(RTCState *s, int a)
+static inline int rtc_to_bcd(RTCState *s, int a)
{
if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
return a;
}
}
-static inline int from_bcd(RTCState *s, int a)
+static inline int rtc_from_bcd(RTCState *s, int a)
{
if (s->cmos_data[RTC_REG_B] & REG_B_DM) {
return a;
{
struct tm *tm = &s->current_tm;
- tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
- tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
- tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
+ tm->tm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
+ tm->tm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
+ tm->tm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
(s->cmos_data[RTC_HOURS] & 0x80)) {
tm->tm_hour += 12;
}
- tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
- tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
- tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
- tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
+ tm->tm_wday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1;
+ tm->tm_mday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
+ tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
+ tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
}
static void rtc_copy_date(RTCState *s)
const struct tm *tm = &s->current_tm;
int year;
- s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
- s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
+ s->cmos_data[RTC_SECONDS] = rtc_to_bcd(s, tm->tm_sec);
+ s->cmos_data[RTC_MINUTES] = rtc_to_bcd(s, tm->tm_min);
if (s->cmos_data[RTC_REG_B] & 0x02) {
/* 24 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
+ s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour);
} else {
/* 12 hour format */
- s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
+ s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour % 12);
if (tm->tm_hour >= 12)
s->cmos_data[RTC_HOURS] |= 0x80;
}
- s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday + 1);
- s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
- s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
+ s->cmos_data[RTC_DAY_OF_WEEK] = rtc_to_bcd(s, tm->tm_wday + 1);
+ s->cmos_data[RTC_DAY_OF_MONTH] = rtc_to_bcd(s, tm->tm_mday);
+ s->cmos_data[RTC_MONTH] = rtc_to_bcd(s, tm->tm_mon + 1);
year = (tm->tm_year - s->base_year) % 100;
if (year < 0)
year += 100;
- s->cmos_data[RTC_YEAR] = to_bcd(s, year);
+ s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year);
}
/* month is between 0 and 11. */
qemu_get_timedate(&tm, 0);
rtc_set_date(s, &tm);
- val = to_bcd(s, (tm.tm_year / 100) + 19);
+ val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
}
printf("%s: conversion failed\n", __FUNCTION__);
}
-static inline uint8_t omap_rtc_bcd(int num)
-{
- return ((num / 10) << 4) | (num % 10);
-}
-
-static inline int omap_rtc_bin(uint8_t num)
-{
- return (num & 15) + 10 * (num >> 4);
-}
-
static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr)
{
struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
switch (offset) {
case 0x00: /* SECONDS_REG */
- return omap_rtc_bcd(s->current_tm.tm_sec);
+ return to_bcd(s->current_tm.tm_sec);
case 0x04: /* MINUTES_REG */
- return omap_rtc_bcd(s->current_tm.tm_min);
+ return to_bcd(s->current_tm.tm_min);
case 0x08: /* HOURS_REG */
if (s->pm_am)
return ((s->current_tm.tm_hour > 11) << 7) |
- omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
+ to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
else
- return omap_rtc_bcd(s->current_tm.tm_hour);
+ return to_bcd(s->current_tm.tm_hour);
case 0x0c: /* DAYS_REG */
- return omap_rtc_bcd(s->current_tm.tm_mday);
+ return to_bcd(s->current_tm.tm_mday);
case 0x10: /* MONTHS_REG */
- return omap_rtc_bcd(s->current_tm.tm_mon + 1);
+ return to_bcd(s->current_tm.tm_mon + 1);
case 0x14: /* YEARS_REG */
- return omap_rtc_bcd(s->current_tm.tm_year % 100);
+ return to_bcd(s->current_tm.tm_year % 100);
case 0x18: /* WEEK_REG */
return s->current_tm.tm_wday;
case 0x20: /* ALARM_SECONDS_REG */
- return omap_rtc_bcd(s->alarm_tm.tm_sec);
+ return to_bcd(s->alarm_tm.tm_sec);
case 0x24: /* ALARM_MINUTES_REG */
- return omap_rtc_bcd(s->alarm_tm.tm_min);
+ return to_bcd(s->alarm_tm.tm_min);
case 0x28: /* ALARM_HOURS_REG */
if (s->pm_am)
return ((s->alarm_tm.tm_hour > 11) << 7) |
- omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
+ to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
else
- return omap_rtc_bcd(s->alarm_tm.tm_hour);
+ return to_bcd(s->alarm_tm.tm_hour);
case 0x2c: /* ALARM_DAYS_REG */
- return omap_rtc_bcd(s->alarm_tm.tm_mday);
+ return to_bcd(s->alarm_tm.tm_mday);
case 0x30: /* ALARM_MONTHS_REG */
- return omap_rtc_bcd(s->alarm_tm.tm_mon + 1);
+ return to_bcd(s->alarm_tm.tm_mon + 1);
case 0x34: /* ALARM_YEARS_REG */
- return omap_rtc_bcd(s->alarm_tm.tm_year % 100);
+ return to_bcd(s->alarm_tm.tm_year % 100);
case 0x40: /* RTC_CTRL_REG */
return (s->pm_am << 3) | (s->auto_comp << 2) |
printf("RTC SEC_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_sec;
- s->ti += omap_rtc_bin(value);
+ s->ti += from_bcd(value);
return;
case 0x04: /* MINUTES_REG */
printf("RTC MIN_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_min * 60;
- s->ti += omap_rtc_bin(value) * 60;
+ s->ti += from_bcd(value) * 60;
return;
case 0x08: /* HOURS_REG */
#endif
s->ti -= s->current_tm.tm_hour * 3600;
if (s->pm_am) {
- s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600;
+ s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
s->ti += ((value >> 7) & 1) * 43200;
} else
- s->ti += omap_rtc_bin(value & 0x3f) * 3600;
+ s->ti += from_bcd(value & 0x3f) * 3600;
return;
case 0x0c: /* DAYS_REG */
printf("RTC DAY_REG <-- %02x\n", value);
#endif
s->ti -= s->current_tm.tm_mday * 86400;
- s->ti += omap_rtc_bin(value) * 86400;
+ s->ti += from_bcd(value) * 86400;
return;
case 0x10: /* MONTHS_REG */
printf("RTC MTH_REG <-- %02x\n", value);
#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
- new_tm.tm_mon = omap_rtc_bin(value);
+ new_tm.tm_mon = from_bcd(value);
ti[0] = mktimegm(&s->current_tm);
ti[1] = mktimegm(&new_tm);
} else {
/* A less accurate version */
s->ti -= s->current_tm.tm_mon * 2592000;
- s->ti += omap_rtc_bin(value) * 2592000;
+ s->ti += from_bcd(value) * 2592000;
}
return;
printf("RTC YRS_REG <-- %02x\n", value);
#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
- new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100);
+ new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
ti[0] = mktimegm(&s->current_tm);
ti[1] = mktimegm(&new_tm);
} else {
/* A less accurate version */
s->ti -= (s->current_tm.tm_year % 100) * 31536000;
- s->ti += omap_rtc_bin(value) * 31536000;
+ s->ti += from_bcd(value) * 31536000;
}
return;
#ifdef ALMDEBUG
printf("ALM SEC_REG <-- %02x\n", value);
#endif
- s->alarm_tm.tm_sec = omap_rtc_bin(value);
+ s->alarm_tm.tm_sec = from_bcd(value);
omap_rtc_alarm_update(s);
return;
#ifdef ALMDEBUG
printf("ALM MIN_REG <-- %02x\n", value);
#endif
- s->alarm_tm.tm_min = omap_rtc_bin(value);
+ s->alarm_tm.tm_min = from_bcd(value);
omap_rtc_alarm_update(s);
return;
#endif
if (s->pm_am)
s->alarm_tm.tm_hour =
- ((omap_rtc_bin(value & 0x3f)) % 12) +
+ ((from_bcd(value & 0x3f)) % 12) +
((value >> 7) & 1) * 12;
else
- s->alarm_tm.tm_hour = omap_rtc_bin(value);
+ s->alarm_tm.tm_hour = from_bcd(value);
omap_rtc_alarm_update(s);
return;
#ifdef ALMDEBUG
printf("ALM DAY_REG <-- %02x\n", value);
#endif
- s->alarm_tm.tm_mday = omap_rtc_bin(value);
+ s->alarm_tm.tm_mday = from_bcd(value);
omap_rtc_alarm_update(s);
return;
#ifdef ALMDEBUG
printf("ALM MON_REG <-- %02x\n", value);
#endif
- s->alarm_tm.tm_mon = omap_rtc_bin(value);
+ s->alarm_tm.tm_mon = from_bcd(value);
omap_rtc_alarm_update(s);
return;
#ifdef ALMDEBUG
printf("ALM YRS_REG <-- %02x\n", value);
#endif
- s->alarm_tm.tm_year = omap_rtc_bin(value);
+ s->alarm_tm.tm_year = from_bcd(value);
omap_rtc_alarm_update(s);
return;
menelaus_update(s);
}
-static inline uint8_t to_bcd(int val)
-{
- return ((val / 10) << 4) | (val % 10);
-}
-
-static inline int from_bcd(uint8_t val)
-{
- return ((val >> 4) * 10) + (val & 0x0f);
-}
-
static void menelaus_gpio_set(void *opaque, int line, int level)
{
MenelausState *s = (MenelausState *) opaque;
struct Monitor;
typedef struct Monitor Monitor;
+/* Convert a byte between binary and BCD. */
+static inline uint8_t to_bcd(uint8_t val)
+{
+ return ((val / 10) << 4) | (val % 10);
+}
+
+static inline uint8_t from_bcd(uint8_t val)
+{
+ return ((val >> 4) * 10) + (val & 0x0f);
+}
+
#include "module.h"
#endif /* dyngen-exec.h hack */