2018-03-13 03:46:10 +01:00
|
|
|
/*
|
2022-10-27 17:08:58 -04:00
|
|
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
|
|
|
|
* running old operating systems and software designed for IBM
|
|
|
|
|
* PC systems and compatibles from 1981 through fairly recent
|
|
|
|
|
* system designs based on the PCI bus.
|
2018-03-13 03:46:10 +01:00
|
|
|
*
|
2022-10-27 17:08:58 -04:00
|
|
|
* This file is part of the 86Box distribution.
|
2018-03-13 03:46:10 +01:00
|
|
|
*
|
2022-11-13 16:37:58 -05:00
|
|
|
* Handling of the PS/2 series CMOS devices.
|
2018-03-13 03:46:10 +01:00
|
|
|
*
|
2020-03-25 00:46:02 +02:00
|
|
|
*
|
2018-03-13 03:46:10 +01:00
|
|
|
*
|
2022-10-27 17:08:58 -04:00
|
|
|
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
2023-01-06 15:36:29 -05:00
|
|
|
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
2018-03-13 03:46:10 +01:00
|
|
|
*
|
2023-01-06 15:36:29 -05:00
|
|
|
* Copyright 2017-2018 Fred N. van Kempen.
|
2022-10-27 17:08:58 -04:00
|
|
|
* Copyright 2008-2018 Sarah Walker.
|
2018-03-13 03:46:10 +01:00
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the:
|
|
|
|
|
*
|
|
|
|
|
* Free Software Foundation, Inc.
|
|
|
|
|
* 59 Temple Place - Suite 330
|
|
|
|
|
* Boston, MA 02111-1307
|
|
|
|
|
* USA.
|
|
|
|
|
*/
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
2017-05-05 01:49:42 +02:00
|
|
|
#include <stdlib.h>
|
2017-09-25 04:31:20 -04:00
|
|
|
#include <wchar.h>
|
2020-03-29 14:24:42 +02:00
|
|
|
#include <86box/86box.h>
|
|
|
|
|
#include <86box/machine.h>
|
|
|
|
|
#include <86box/device.h>
|
|
|
|
|
#include <86box/io.h>
|
|
|
|
|
#include <86box/mem.h>
|
|
|
|
|
#include <86box/timer.h>
|
|
|
|
|
#include <86box/nvr.h>
|
|
|
|
|
#include <86box/nvr_ps2.h>
|
|
|
|
|
#include <86box/rom.h>
|
2017-05-05 01:49:42 +02:00
|
|
|
|
2023-06-28 13:46:28 -04:00
|
|
|
typedef struct ps2_nvr_t {
|
2022-09-18 17:11:43 -04:00
|
|
|
int addr;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
uint8_t *ram;
|
|
|
|
|
int size;
|
2018-09-15 16:15:39 +02:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
char *fn;
|
2017-05-05 01:49:42 +02:00
|
|
|
} ps2_nvr_t;
|
|
|
|
|
|
2018-03-13 03:46:10 +01:00
|
|
|
static uint8_t
|
|
|
|
|
ps2_nvr_read(uint16_t port, void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2022-09-18 17:11:43 -04:00
|
|
|
ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
|
|
|
|
|
uint8_t ret = 0xff;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
|
|
|
|
switch (port) {
|
2022-09-18 17:11:43 -04:00
|
|
|
case 0x74:
|
|
|
|
|
ret = nvr->addr & 0xff;
|
|
|
|
|
break;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
case 0x75:
|
|
|
|
|
ret = nvr->addr >> 8;
|
|
|
|
|
break;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
case 0x76:
|
|
|
|
|
ret = nvr->ram[nvr->addr];
|
|
|
|
|
break;
|
2023-06-28 13:46:28 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2018-03-13 03:46:10 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return ret;
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-13 03:46:10 +01:00
|
|
|
static void
|
|
|
|
|
ps2_nvr_write(uint16_t port, uint8_t val, void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2022-09-18 17:11:43 -04:00
|
|
|
ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
|
|
|
|
switch (port) {
|
2022-09-18 17:11:43 -04:00
|
|
|
case 0x74:
|
|
|
|
|
nvr->addr = (nvr->addr & 0x1f00) | val;
|
|
|
|
|
break;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
case 0x75:
|
|
|
|
|
nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8);
|
|
|
|
|
break;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
case 0x76:
|
|
|
|
|
nvr->ram[nvr->addr] = val;
|
|
|
|
|
break;
|
2023-06-28 13:46:28 -04:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2018-03-13 03:46:10 +01:00
|
|
|
}
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-13 03:46:10 +01:00
|
|
|
static void *
|
2018-03-19 01:02:04 +01:00
|
|
|
ps2_nvr_init(const device_t *info)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2018-03-13 03:46:10 +01:00
|
|
|
ps2_nvr_t *nvr;
|
2022-09-18 17:11:43 -04:00
|
|
|
FILE *f = NULL;
|
|
|
|
|
int c;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
nvr = (ps2_nvr_t *) malloc(sizeof(ps2_nvr_t));
|
2018-03-13 03:46:10 +01:00
|
|
|
memset(nvr, 0x00, sizeof(ps2_nvr_t));
|
2018-09-15 16:15:39 +02:00
|
|
|
|
2022-07-19 16:32:23 +02:00
|
|
|
if (info->local)
|
|
|
|
|
nvr->size = 2048;
|
|
|
|
|
else
|
|
|
|
|
nvr->size = 8192;
|
|
|
|
|
|
2018-09-15 16:15:39 +02:00
|
|
|
/* Set up the NVR file's name. */
|
2022-09-18 17:11:43 -04:00
|
|
|
c = strlen(machine_get_internal_name()) + 9;
|
|
|
|
|
nvr->fn = (char *) malloc(c + 1);
|
2021-03-14 20:35:01 +01:00
|
|
|
sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name());
|
2018-09-15 16:15:39 +02:00
|
|
|
|
2018-03-13 03:46:10 +01:00
|
|
|
io_sethandler(0x0074, 3,
|
2022-09-18 17:11:43 -04:00
|
|
|
ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr);
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2021-03-14 20:35:01 +01:00
|
|
|
f = nvr_fopen(nvr->fn, "rb");
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2022-09-18 17:11:43 -04:00
|
|
|
nvr->ram = (uint8_t *) malloc(nvr->size);
|
2022-07-19 16:32:23 +02:00
|
|
|
memset(nvr->ram, 0xff, nvr->size);
|
2018-03-13 03:46:10 +01:00
|
|
|
if (f != NULL) {
|
2022-09-18 17:11:43 -04:00
|
|
|
if (fread(nvr->ram, 1, nvr->size, f) != nvr->size)
|
|
|
|
|
fatal("ps2_nvr_init(): Error reading EEPROM data\n");
|
|
|
|
|
fclose(f);
|
2018-03-13 03:46:10 +01:00
|
|
|
}
|
|
|
|
|
|
2023-05-11 03:02:36 -04:00
|
|
|
return nvr;
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-13 03:46:10 +01:00
|
|
|
static void
|
|
|
|
|
ps2_nvr_close(void *priv)
|
2017-05-05 01:49:42 +02:00
|
|
|
{
|
2022-09-18 17:11:43 -04:00
|
|
|
ps2_nvr_t *nvr = (ps2_nvr_t *) priv;
|
|
|
|
|
FILE *f = NULL;
|
2018-03-13 03:46:10 +01:00
|
|
|
|
2021-03-14 20:35:01 +01:00
|
|
|
f = nvr_fopen(nvr->fn, "wb");
|
2018-03-13 03:46:10 +01:00
|
|
|
|
|
|
|
|
if (f != NULL) {
|
2022-09-18 17:11:43 -04:00
|
|
|
(void) fwrite(nvr->ram, nvr->size, 1, f);
|
|
|
|
|
fclose(f);
|
2018-03-13 03:46:10 +01:00
|
|
|
}
|
|
|
|
|
|
2022-07-19 16:32:23 +02:00
|
|
|
if (nvr->ram != NULL)
|
|
|
|
|
free(nvr->ram);
|
|
|
|
|
|
2018-03-13 03:46:10 +01:00
|
|
|
free(nvr);
|
2017-05-05 01:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-19 01:02:04 +01:00
|
|
|
const device_t ps2_nvr_device = {
|
2022-09-18 17:11:43 -04:00
|
|
|
.name = "PS/2 Secondary NVRAM for PS/2 Models 70-80",
|
2022-03-13 09:15:11 -04:00
|
|
|
.internal_name = "ps2_nvr",
|
2022-09-18 17:11:43 -04:00
|
|
|
.flags = 0,
|
|
|
|
|
.local = 0,
|
|
|
|
|
.init = ps2_nvr_init,
|
|
|
|
|
.close = ps2_nvr_close,
|
|
|
|
|
.reset = NULL,
|
2022-03-13 09:15:11 -04:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:11:43 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2017-05-05 01:49:42 +02:00
|
|
|
};
|
2022-07-19 16:32:23 +02:00
|
|
|
|
|
|
|
|
const device_t ps2_nvr_55ls_device = {
|
2022-09-18 17:11:43 -04:00
|
|
|
.name = "PS/2 Secondary NVRAM for PS/2 Models 55LS-65SX",
|
2022-07-19 16:32:23 +02:00
|
|
|
.internal_name = "ps2_nvr_55ls",
|
2022-09-18 17:11:43 -04:00
|
|
|
.flags = 0,
|
|
|
|
|
.local = 1,
|
|
|
|
|
.init = ps2_nvr_init,
|
|
|
|
|
.close = ps2_nvr_close,
|
|
|
|
|
.reset = NULL,
|
2022-07-19 16:32:23 +02:00
|
|
|
{ .available = NULL },
|
|
|
|
|
.speed_changed = NULL,
|
2022-09-18 17:11:43 -04:00
|
|
|
.force_redraw = NULL,
|
|
|
|
|
.config = NULL
|
2022-07-19 16:32:23 +02:00
|
|
|
};
|