Finished the VIA machine.

This commit is contained in:
OBattler
2020-01-14 02:14:39 +01:00
parent 426bf8c46e
commit da82e6a5eb
20 changed files with 863 additions and 589 deletions

View File

@@ -189,16 +189,16 @@
* including the later update (DS12887A) which implemented a
* "century" register to be compatible with Y2K.
*
* Version: @(#)nvr_at.c 1.0.16 2019/11/19
* Version: @(#)nvr_at.c 1.0.17 2020/01/13
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Mahod,
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2019 Miran Grca.
* Copyright 2008-2019 Sarah Walker.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2020 Miran Grca.
* Copyright 2008-2020 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -281,6 +281,9 @@
# define REGD_VRT 0x80
#define RTC_CENTURY_AT 0x32 /* century register for AT etc */
#define RTC_CENTURY_PS 0x37 /* century register for PS/1 PS/2 */
#define RTC_ALDAY 0x7D /* VIA VT82C586B - alarm day */
#define RTC_ALMONTH 0x7E /* VIA VT82C586B - alarm month */
#define RTC_CENTURY_VIA 0x7F /* century register for VIA VT82C586B */
#define RTC_REGS 14 /* number of registers */
@@ -290,7 +293,7 @@ typedef struct {
uint8_t cent;
uint8_t def;
uint8_t addr;
uint8_t addr[8];
int16_t count, state;
@@ -402,6 +405,20 @@ check_alarm(nvr_t *nvr, int8_t addr)
}
/* Check for VIA stuff. */
static int8_t
check_alarm_via(nvr_t *nvr, int8_t addr, int8_t addr_2)
{
local_t *local = (local_t *)nvr->data;
if (local->cent == RTC_CENTURY_VIA) {
return((nvr->regs[addr_2] == nvr->regs[addr]) ||
((nvr->regs[addr_2] & AL_DONTCARE) == AL_DONTCARE));
} else
return 0;
}
/* Update the NVR registers from the internal clock. */
static void
timer_update(void *priv)
@@ -425,7 +442,9 @@ timer_update(void *priv)
/* Check for any alarms we need to handle. */
if (check_alarm(nvr, RTC_SECONDS) &&
check_alarm(nvr, RTC_MINUTES) &&
check_alarm(nvr, RTC_HOURS)) {
check_alarm(nvr, RTC_HOURS) &&
check_alarm_via(nvr, RTC_DOM, RTC_ALDAY) &&
check_alarm_via(nvr, RTC_MONTH, RTC_ALMONTH)) {
nvr->regs[RTC_REGC] |= REGC_AF;
if (nvr->regs[RTC_REGB] & REGB_AIE) {
nvr->regs[RTC_REGC] |= REGC_IRQF;
@@ -535,12 +554,13 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
local_t *local = (local_t *)nvr->data;
struct tm tm;
uint8_t old;
uint8_t addr_id = (addr & 0x0e) >> 1;
sub_cycles(ISA_CYCLES(8));
if (addr & 1) {
old = nvr->regs[local->addr];
switch(local->addr) {
old = nvr->regs[local->addr[addr_id]];
switch(local->addr[addr_id]) {
case RTC_REGA:
nvr->regs[RTC_REGA] = val;
timer_load_count(nvr);
@@ -560,15 +580,15 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
break;
default: /* non-RTC registers are just NVRAM */
if (nvr->regs[local->addr] != val) {
nvr->regs[local->addr] = val;
if (nvr->regs[local->addr[addr_id]] != val) {
nvr->regs[local->addr[addr_id]] = val;
nvr_dosave = 1;
}
break;
}
if ((local->addr < RTC_REGA) || ((local->cent != 0xff) && (local->addr == local->cent))) {
if ((local->addr != 1) && (local->addr != 3) && (local->addr != 5)) {
if ((local->addr[addr_id] < RTC_REGA) || ((local->cent != 0xff) && (local->addr[addr_id] == local->cent))) {
if ((local->addr[addr_id] != 1) && (local->addr[addr_id] != 3) && (local->addr[addr_id] != 5)) {
if ((old != val) && !(time_sync & TIME_SYNC_ENABLED)) {
/* Update internal clock. */
time_get(nvr, &tm);
@@ -578,7 +598,10 @@ nvr_write(uint16_t addr, uint8_t val, void *priv)
}
}
} else {
local->addr = (val & (nvr->size - 1));
local->addr[addr_id] = (val & (nvr->size - 1));
/* Some chipsets use a 256 byte NVRAM but ports 70h and 71h always access only 128 bytes. */
if (addr_id == 0x0)
local->addr[addr_id] &= 0x7f;
if (!(machines[machine].flags & MACHINE_MCA) &&
!(machines[machine].flags & MACHINE_NONMI))
nmi_mask = (~val & 0x80);
@@ -593,10 +616,11 @@ nvr_read(uint16_t addr, void *priv)
nvr_t *nvr = (nvr_t *)priv;
local_t *local = (local_t *)nvr->data;
uint8_t ret;
uint8_t addr_id = (addr & 0x0e) >> 1;
sub_cycles(ISA_CYCLES(8));
if (addr & 1) switch(local->addr) {
if (addr & 1) switch(local->addr[addr_id]) {
case RTC_REGA:
ret = (nvr->regs[RTC_REGA] & 0x7f) | local->stat;
break;
@@ -613,10 +637,10 @@ nvr_read(uint16_t addr, void *priv)
break;
default:
ret = nvr->regs[local->addr];
ret = nvr->regs[local->addr[addr_id]];
break;
} else
ret = local->addr;
ret = local->addr[addr_id];
return(ret);
}
@@ -692,6 +716,14 @@ nvr_at_speed_changed(void *priv)
}
void
nvr_at_handler(int set, uint16_t base, nvr_t *nvr)
{
io_handler(set, base, 2,
nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr);
}
static void *
nvr_at_init(const device_t *info)
{
@@ -710,7 +742,7 @@ nvr_at_init(const device_t *info)
/* This is machine specific. */
nvr->size = machines[machine].nvrmask + 1;
local->def = 0x00;
switch(info->local) {
switch(info->local & 7) {
case 0: /* standard AT, no century register */
nvr->irq = 8;
local->cent = 0xff;
@@ -738,6 +770,10 @@ nvr_at_init(const device_t *info)
local->def = 0xff;
break;
case 5: /* VIA VT82C586B */
nvr->irq = 8;
local->cent = RTC_CENTURY_VIA;
break;
}
/* Set up any local handlers here. */
@@ -758,6 +794,10 @@ nvr_at_init(const device_t *info)
/* Set up the I/O handler for this device. */
io_sethandler(0x0070, 2,
nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr);
if (info->local & 8) {
io_sethandler(0x0072, 2,
nvr_read,NULL,NULL, nvr_write,NULL,NULL, nvr);
}
return(nvr);
}
@@ -829,3 +869,13 @@ const device_t ibmat_nvr_device = {
NULL, nvr_at_speed_changed,
NULL
};
const device_t via_nvr_device = {
"VIA PC/AT NVRAM",
DEVICE_ISA | DEVICE_AT,
9,
nvr_at_init, nvr_at_close, NULL,
NULL, nvr_at_speed_changed,
NULL
};