Some changes to the (AT) NVR code.

This commit is contained in:
OBattler
2019-11-19 04:47:00 +01:00
parent 0d97fadb6e
commit 26009044d7
2 changed files with 38 additions and 59 deletions

View File

@@ -8,7 +8,7 @@
*
* Implement a generic NVRAM/CMOS/RTC device.
*
* Version: @(#)nvr.c 1.0.18 2019/03/16
* Version: @(#)nvr.c 1.0.19 2019/11/19
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>,
* David Hrdlička, <hrdlickadavid@outlook.com>
@@ -156,7 +156,7 @@ onesec_timer(void *priv)
nvr->onesec_cnt = 0;
}
timer_advance_u64(&nvr->onesec_time, (10000ULL * TIMER_USEC));
timer_advance_u64(&nvr->onesec_time, (uint64_t)(10000ULL * TIMER_USEC));
}

View File

@@ -189,7 +189,7 @@
* including the later update (DS12887A) which implemented a
* "century" register to be compatible with Y2K.
*
* Version: @(#)nvr_at.c 1.0.15 2019/03/16
* Version: @(#)nvr_at.c 1.0.16 2019/11/19
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -292,6 +292,8 @@ typedef struct {
uint8_t addr;
int16_t count, state;
uint64_t ecount,
rtc_time;
pc_timer_t update_timer,
@@ -450,43 +452,29 @@ timer_update(void *priv)
}
static double
timer_nvr_period(nvr_t *nvr)
static void
timer_load_count(nvr_t *nvr)
{
double dusec = (double) TIMER_USEC;
int c = nvr->regs[RTC_REGA] & REGA_RS;
local_t *local = (local_t *) nvr->data;
switch (nvr->regs[RTC_REGA] & REGA_RS) {
if ((nvr->regs[RTC_REGA] & 0x70) != 0x20) {
local->state = 0;
return;
}
local->state = 1;
switch (c) {
case 0:
local->state = 0;
break;
case 1: case 2:
local->count = 1 << (c + 6);
break;
default:
return 0.0;
case 1:
case 8:
return 3906.25 * dusec;
case 2:
case 9:
return 7812.5 * dusec;
case 3:
return 122.070 * dusec;
case 4:
return 244.141 * dusec;
case 5:
return 488.281 * dusec;
case 6:
return 976.5625 * dusec;
case 7:
return 1953.125 * dusec;
case 10:
return 15625.0 * dusec;
case 11:
return 31250.0 * dusec;
case 12:
return 62500.0 * dusec;
case 13:
return 125000.0 * dusec;
case 14:
return 250000.0 * dusec;
case 15:
return 500000.0 * dusec;
local->count = 1 << (c - 1);
break;
}
}
@@ -497,13 +485,16 @@ timer_intr(void *priv)
nvr_t *nvr = (nvr_t *)priv;
local_t *local = (local_t *)nvr->data;
if (nvr->regs[RTC_REGA] & REGA_RS) {
local->rtc_time = timer_nvr_period(nvr);
timer_advance_u64(&local->rtc_timer, (uint64_t) local->rtc_time);
} else {
local->rtc_time = 0ULL;
timer_advance_u64(&local->rtc_timer, RTCCONST);
if (local->state == 1) {
local->count--;
if (local->count == 0)
timer_load_count(nvr);
else
return;
} else
return;
}
nvr->regs[RTC_REGC] |= REGC_PF;
if (nvr->regs[RTC_REGB] & REGB_PIE) {
@@ -536,20 +527,6 @@ timer_tick(nvr_t *nvr)
}
static void
nvr_pie_start(nvr_t *nvr)
{
local_t *local = (local_t *)nvr->data;
local->rtc_time = 0ULL;
timer_disable(&local->rtc_timer);
if ((nvr->regs[RTC_REGA] & REGA_RS) && ((nvr->regs[RTC_REGA] & 0x70) == 0x20)) {
local->rtc_time = timer_nvr_period(nvr);
timer_set_delay_u64(&local->rtc_timer, local->rtc_time);
}
}
/* Write to one of the NVR registers. */
static void
nvr_write(uint16_t addr, uint8_t val, void *priv)
@@ -566,7 +543,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
switch(local->addr) {
case RTC_REGA:
nvr->regs[RTC_REGA] = val;
nvr_pie_start(nvr);
timer_load_count(nvr);
break;
case RTC_REGB:
@@ -704,8 +681,7 @@ nvr_at_speed_changed(void *priv)
local_t *local = (local_t *) nvr->data;
timer_disable(&local->rtc_timer);
if (local->rtc_time > 0ULL)
timer_set_delay_u64(&local->rtc_timer, local->rtc_time);
timer_set_delay_u64(&local->rtc_timer, RTCCONST);
timer_disable(&local->update_timer);
if (local->ecount > 0ULL)
@@ -774,7 +750,10 @@ nvr_at_init(const device_t *info)
/* Start the timers. */
timer_add(&local->update_timer, timer_update, nvr, 0);
timer_add(&local->rtc_timer, timer_intr, nvr, 0);
timer_load_count(nvr);
timer_set_delay_u64(&local->rtc_timer, RTCCONST);
/* Set up the I/O handler for this device. */
io_sethandler(0x0070, 2,