#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);
}
