Files
86Box/src/device/ast_nvr.c
win2kgamer 5c9fa029bf Implement the VLSI SuperCore/Wildcat chipsets (#6247)
* Add the VLSI SuperCore and Wildcat chipsets

* Disable logging and minor cleanups

* Add the AST Bravo MS P/90 (Rattler)

* Add the AT&T Globalyst 620 (NCR 3248)

* Add the DEC Celebris 5xx

* Add the DFI G586VPM Rev C

* Add the Packard Bell PB600

* Fix southbridge PCI Command Register writes

* Block the Cyrix 6x86 on incompatible machines

* Rename the AT&T Globalyst 620 to include the names of the NCR counterparts

* Add the Zeos Pantera Wildcat

* Add RZ-1001 variant of the RZ-1000 PCI IDE controller and made the Zeos Pantera Wildcat use it

* Add the Micronics M54Si

* Update machine_table.c

* Re-add new machines to machine table

* Update machine inits to use new KBC device names

* Use correct machine init method as NVRAM init is done by the chipset code

* Use a Phoenix KBC for the AST Bravo since the BIOS calls command D5h to show the KBC revision

* Update KBC comments in machine table

* Update VLSI 59x chipset comments

* Update machine inits for new super I/O code

* Reorganize machines and update comments

* AST readout device actually has multiple indexed registers

* Implement the AST Bravo MS ECP DMA configuration

* Implement jumpered/hardwired ECP DMA for the remaining machines

* Fix ECP DMA on the AST Bravo MS

* Move the DEC Celebris to the Socket 4/5 category

* Implement SMI I/O port read, fixes APM init on AT&T, Micronics and Zeos machines

* Convert AST readout device to new logging system

* Update KBC init to new method

* Cleanups
2025-09-29 04:48:33 +02:00

181 lines
3.9 KiB
C

/*
* 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.
*
* This file is part of the 86Box distribution.
*
* Implementation of the AST Bravo MS secondary NVR
*
*
*
* Authors: win2kgamer
*
* Copyright 2025 win2kgamer.
*/
#ifdef ENABLE_AST_NVR_LOG
#include <stdarg.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#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/rom.h>
#include <86box/log.h>
#ifdef ENABLE_AST_NVR_LOG
int ast_nvr_do_log = ENABLE_AST_NVR_LOG;
static void
ast_nvr_log(void *priv, const char *fmt, ...)
{
if (ast_nvr_do_log) {
va_list ap;
va_start(ap, fmt);
log_out(priv, fmt, ap);
va_end(ap);
}
}
#else
# define ast_nvr_log(fmt, ...)
#endif
typedef struct ast_nvr_t {
int addr;
int bank;
uint8_t *ram;
int size;
char *fn;
void * log; // New logging system
} ast_nvr_t;
static uint8_t
ast_nvr_read(uint16_t port, void *priv)
{
ast_nvr_t *nvr = (ast_nvr_t *) priv;
uint8_t ret = 0xff;
switch (port) {
case 0x800 ... 0x8FF:
nvr->addr = ((nvr->bank << 8) + (port - 0x800));
ret = nvr->ram[nvr->addr];
break;
default:
break;
}
ast_nvr_log(nvr->log, "AST NVR Read [%02X:%02X] = %02X\n", nvr->bank, port, ret);
return ret;
}
static void
ast_nvr_write(uint16_t port, uint8_t val, void *priv)
{
ast_nvr_t *nvr = (ast_nvr_t *) priv;
ast_nvr_log(nvr->log, "AST NVR Write [%02X:%02X] = %02X\n", nvr->bank, port, val);
switch (port) {
case 0x800 ... 0x8FF:
nvr->addr = ((nvr->bank << 8) + (port - 0x800));
nvr->ram[nvr->addr] = val;
break;
case 0xC00:
nvr->bank = val;
default:
break;
}
}
static void *
ast_nvr_init(const device_t *info)
{
ast_nvr_t *nvr;
FILE *fp = NULL;
int c;
nvr = (ast_nvr_t *) calloc(1, sizeof(ast_nvr_t));
memset(nvr, 0x00, sizeof(ast_nvr_t));
nvr->log = log_open("ASTNVR");
nvr->size = 8192;
/* Set up the NVR file's name */
c = strlen(machine_get_internal_name()) + 9;
nvr->fn = (char *) calloc(1, (c + 1));
sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name());
io_sethandler(0x0800, 0x100,
ast_nvr_read, NULL, NULL, ast_nvr_write, NULL, NULL, nvr);
io_sethandler(0x0C00, 0x01,
ast_nvr_read, NULL, NULL, ast_nvr_write, NULL, NULL, nvr);
fp = nvr_fopen(nvr->fn, "rb");
nvr->ram = (uint8_t *) calloc(1, nvr->size);
memset(nvr->ram, 0xff, nvr->size);
if (fp != NULL) {
if (fread(nvr->ram, 1, nvr->size, fp) != nvr->size)
fatal("ast_nvr_init(): Error reading EEPROM data\n");
fclose(fp);
}
return nvr;
}
static void
ast_nvr_close (void *priv)
{
ast_nvr_t *nvr = (ast_nvr_t *) priv;
FILE *fp = NULL;
fp = nvr_fopen(nvr->fn, "wb");
if (fp != NULL) {
(void) fwrite(nvr->ram, nvr->size, 1, fp);
fclose(fp);
}
if (nvr->ram != NULL)
free(nvr->ram);
if (nvr->log != NULL) {
log_close(nvr->log);
nvr->log = NULL;
}
free(nvr);
}
const device_t ast_nvr_device = {
.name = "AST Secondary NVRAM for Bravo MS",
.internal_name = "ast_nvr",
.flags = 0,
.local = 0,
.init = ast_nvr_init,
.close = ast_nvr_close,
.reset = NULL,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};