pcem/src/nvr_tc8521.c
SarahW a7d006b637 Rewrote timer code.
The new code is based on timestamps, rather than delays. This eliminates the
need to update every timer in timer_process(), which cost a non-trivial amount
of CPU time on low-end machines.

This involved changes to every user of the timer code, so this change almost
certainly introduces bugs.
2018-08-02 22:06:10 +01:00

101 lines
2.3 KiB
C

#include <stdio.h>
#include "ibm.h"
#include "io.h"
#include "nvr.h"
#include "nvr_tc8521.h"
#include "rtc_tc8521.h"
#include "pic.h"
#include "timer.h"
#include "rtc.h"
#include "paths.h"
#include "config.h"
#include "nmi.h"
static pc_timer_t nvr_onesec_timer;
static int nvr_onesec_cnt = 0;
static void tc8521_onesec(void *p)
{
nvr_onesec_cnt++;
if (nvr_onesec_cnt >= 100)
{
tc8521_tick();
nvr_onesec_cnt = 0;
}
timer_advance_u64(&nvr_onesec_timer, 10000 * TIMER_USEC);
}
void write_tc8521(uint16_t addr, uint8_t val, void *priv)
{
uint8_t page = nvrram[0x0D] & 3;
addr &= 0x0F;
if (addr < 0x0D) addr += 16 * page;
if (addr >= 0x10 && nvrram[addr] != val)
nvr_dosave = 1;
nvrram[addr] = val;
}
uint8_t read_tc8521(uint16_t addr, void *priv)
{
uint8_t page = nvrram[0x0D] & 3;
addr &= 0x0F;
if (addr < 0x0D) addr += 16 * page;
return nvrram[addr];
}
void tc8521_loadnvr()
{
FILE *f;
nvrmask=63;
oldromset=romset;
switch (romset)
{
case ROM_T1000: f = nvrfopen("t1000.nvr", "rb"); break;
case ROM_T1200: f = nvrfopen("t1200.nvr", "rb"); break;
default: return;
}
if (!f)
{
memset(nvrram,0xFF,64);
nvrram[0x0E] = 0; /* Test register */
if (!enable_sync)
{
memset(nvrram, 0, 16);
}
return;
}
fread(nvrram,64,1,f);
if (enable_sync)
tc8521_internal_sync(nvrram);
else
tc8521_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */
fclose(f);
}
void tc8521_savenvr()
{
FILE *f;
switch (oldromset)
{
case ROM_T1000: f = nvrfopen("t1000.nvr", "wb"); break;
case ROM_T1200: f = nvrfopen("t1200.nvr", "wb"); break;
default: return;
}
fwrite(nvrram,64,1,f);
fclose(f);
}
void nvr_tc8521_init()
{
io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL);
timer_add(&nvr_onesec_timer, tc8521_onesec, NULL, 1);
}