Files
86Box/src/chipset/sis_85c310.c

154 lines
3.6 KiB
C
Raw Normal View History

#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
2023-06-26 12:47:04 -04:00
#include <86box/plat_unused.h>
#include <86box/chipset.h>
2023-06-26 22:31:03 -04:00
typedef struct rabbit_t {
uint8_t cur_reg;
uint8_t tries;
uint8_t regs[258];
} rabbit_t;
static void
rabbit_recalcmapping(rabbit_t *dev)
{
2023-06-01 18:32:25 -04:00
uint32_t shread;
uint32_t shwrite;
uint32_t shflags = 0;
2022-09-18 17:12:38 -04:00
shread = !!(dev->regs[0x101] & 0x40);
shwrite = !!(dev->regs[0x100] & 0x02);
shflags = shread ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= shwrite ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
2022-09-18 17:12:38 -04:00
shadowbios = !!shread;
shadowbios_write = !!shwrite;
#ifdef USE_SHADOW_C0000
mem_set_mem_state(0x000c0000, 0x00040000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
#else
mem_set_mem_state(0x000e0000, 0x00020000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
#endif
switch (dev->regs[0x100] & 0x09) {
2022-09-18 17:12:38 -04:00
case 0x01:
/* The one BIOS we use seems to use something else to control C0000-DFFFF shadow,
no idea what. */
#ifdef USE_SHADOW_C0000
2022-09-18 17:12:38 -04:00
/* 64K at 0C0000-0CFFFF */
mem_set_mem_state(0x000c0000, 0x00010000, shflags);
/* FALLTHROUGH */
#endif
2022-09-18 17:12:38 -04:00
case 0x00:
/* 64K at 0F0000-0FFFFF */
mem_set_mem_state(0x000f0000, 0x00010000, shflags);
break;
2022-09-18 17:12:38 -04:00
case 0x09:
#ifdef USE_SHADOW_C0000
2022-09-18 17:12:38 -04:00
/* 128K at 0C0000-0DFFFF */
mem_set_mem_state(0x000c0000, 0x00020000, shflags);
/* FALLTHROUGH */
#endif
2022-09-18 17:12:38 -04:00
case 0x08:
/* 128K at 0E0000-0FFFFF */
mem_set_mem_state(0x000e0000, 0x00020000, shflags);
break;
2023-06-26 12:47:04 -04:00
default:
break;
}
flushmmucache();
}
static void
rabbit_write(uint16_t addr, uint8_t val, void *priv)
{
rabbit_t *dev = (rabbit_t *) priv;
switch (addr) {
2022-09-18 17:12:38 -04:00
case 0x22:
dev->cur_reg = val;
dev->tries = 0;
break;
case 0x23:
if (dev->cur_reg == 0x83) {
if (dev->tries < 0x02) {
dev->regs[dev->tries++ | 0x100] = val;
if (dev->tries == 0x02)
rabbit_recalcmapping(dev);
}
} else
dev->regs[dev->cur_reg] = val;
break;
2023-06-26 12:47:04 -04:00
default:
break;
}
}
static uint8_t
rabbit_read(uint16_t addr, void *priv)
{
2022-09-18 17:12:38 -04:00
uint8_t ret = 0xff;
rabbit_t *dev = (rabbit_t *) priv;
switch (addr) {
2022-09-18 17:12:38 -04:00
case 0x23:
if (dev->cur_reg == 0x83) {
if (dev->tries < 0x02)
ret = dev->regs[dev->tries++ | 0x100];
} else
ret = dev->regs[dev->cur_reg];
break;
2023-06-26 22:31:03 -04:00
2023-06-26 12:47:04 -04:00
default:
break;
}
return ret;
}
static void
rabbit_close(void *priv)
{
rabbit_t *dev = (rabbit_t *) priv;
free(dev);
}
static void *
2023-06-26 12:47:04 -04:00
rabbit_init(UNUSED(const device_t *info))
{
rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t));
memset(dev, 0, sizeof(rabbit_t));
io_sethandler(0x0022, 0x0002, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev);
return dev;
}
const device_t rabbit_device = {
2022-09-18 17:12:38 -04:00
.name = "SiS Rabbit",
2022-03-13 09:21:08 -04:00
.internal_name = "rabbit",
2022-09-18 17:12:38 -04:00
.flags = 0,
.local = 0,
.init = rabbit_init,
.close = rabbit_close,
.reset = NULL,
2022-03-13 09:21:08 -04:00
{ .available = NULL },
.speed_changed = NULL,
2022-09-18 17:12:38 -04:00
.force_redraw = NULL,
.config = NULL
2022-02-18 21:38:51 -05:00
};