Implemented software-requested DMA block transfers, fixes #405, and also fixes UMBPCI's DMACHK ISA DMA tests;
Reworked a few things and re-implemented memory write protection in the SCAT emulation, to require less unusual mappings; Removed two files that should not be there; Made sure all graphics cards' memory mappings are mapped as MEM_MAPPING_EXTERNAL; Added MEM_MAPPING_ROMCS flag to signal that a mapping responds to MEMCS* and made the BIOS and Intel flash mappings use it.
This commit is contained in:
@@ -92,8 +92,6 @@ typedef struct scat_t {
|
||||
mem_mapping_t high_mapping[16];
|
||||
mem_mapping_t remap_mapping[6];
|
||||
mem_mapping_t efff_mapping[44];
|
||||
mem_mapping_t romcs_mapping[8];
|
||||
mem_mapping_t bios_mapping[8];
|
||||
mem_mapping_t ems_mapping[32];
|
||||
} scat_t;
|
||||
|
||||
@@ -123,43 +121,38 @@ static uint8_t scat_in(uint16_t port, void *priv);
|
||||
static void scat_out(uint16_t port, uint8_t val, void *priv);
|
||||
|
||||
|
||||
static void
|
||||
romcs_state_update(scat_t *dev, uint8_t val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (val & 1) {
|
||||
mem_mapping_enable(&dev->romcs_mapping[i << 1]);
|
||||
mem_mapping_enable(&dev->romcs_mapping[(i << 1) + 1]);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->romcs_mapping[i << 1]);
|
||||
mem_mapping_disable(&dev->romcs_mapping[(i << 1) + 1]);
|
||||
}
|
||||
val >>= 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (val & 1) {
|
||||
mem_mapping_enable(&dev->bios_mapping[i << 1]);
|
||||
mem_mapping_enable(&dev->bios_mapping[(i << 1) + 1]);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->bios_mapping[i << 1]);
|
||||
mem_mapping_disable(&dev->bios_mapping[(i << 1) + 1]);
|
||||
}
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shadow_state_update(scat_t *dev)
|
||||
{
|
||||
int i, val;
|
||||
|
||||
uint32_t base, bit, romcs, rommap_r, rommap_w, wp, shflags = 0;
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
val = ((dev->regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL | MEM_WRITE_INTERNAL : MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
mem_set_mem_state((i + 40) << 14, 0x4000, val);
|
||||
val = (dev->regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1;
|
||||
|
||||
base = 0xa0000 + (i << 14);
|
||||
bit = (base - 0xc0000) >> 15;
|
||||
romcs = 0;
|
||||
wp = 0;
|
||||
|
||||
if (base >= 0xc0000) {
|
||||
romcs = dev->regs[SCAT_ROM_ENABLE] & (1 << bit);
|
||||
|
||||
wp = dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << bit);
|
||||
}
|
||||
|
||||
rommap_r = mem_mapping_is_romcs(base, 0) ? romcs : 1;
|
||||
rommap_w = mem_mapping_is_romcs(base, 1) ? romcs : 1;
|
||||
|
||||
shflags = val ? MEM_READ_INTERNAL : (rommap_r ? MEM_READ_EXTERNAL : MEM_READ_DISABLED);
|
||||
|
||||
if (wp)
|
||||
shflags |= MEM_WRITE_DISABLED;
|
||||
else
|
||||
shflags |= (val ? MEM_WRITE_INTERNAL : (rommap_w ? MEM_WRITE_EXTERNAL : MEM_WRITE_DISABLED));
|
||||
|
||||
mem_set_mem_state(base, 0x4000, shflags);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
@@ -1037,6 +1030,8 @@ memmap_state_update(scat_t *dev)
|
||||
}
|
||||
|
||||
set_global_EMS_state(dev, dev->regs[SCAT_EMS_CONTROL] & 0x80);
|
||||
|
||||
flushmmucache_cr3();
|
||||
}
|
||||
|
||||
|
||||
@@ -1118,15 +1113,7 @@ scat_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case SCAT_ROM_ENABLE:
|
||||
romcs_state_update(dev, val);
|
||||
reg_valid = 1;
|
||||
break;
|
||||
|
||||
case SCAT_RAM_WRITE_PROTECT:
|
||||
reg_valid = 1;
|
||||
flushmmucache_cr3();
|
||||
break;
|
||||
|
||||
case SCAT_SHADOW_RAM_ENABLE_1:
|
||||
case SCAT_SHADOW_RAM_ENABLE_2:
|
||||
case SCAT_SHADOW_RAM_ENABLE_3:
|
||||
@@ -1468,7 +1455,9 @@ scat_init(const device_t *info)
|
||||
if (! sx)
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
#if 0
|
||||
mem_mapping_disable(&bios_mapping);
|
||||
#endif
|
||||
|
||||
k = (sx) ? 0x80000 : 0x40000;
|
||||
|
||||
@@ -1514,25 +1503,6 @@ scat_init(const device_t *info)
|
||||
mem_mapping_enable(&dev->efff_mapping[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
mem_mapping_add(&dev->romcs_mapping[i], 0xc0000 + (i << 14), 0x4000,
|
||||
mem_read_bios, mem_read_biosw, mem_read_biosl,
|
||||
mem_write_null, mem_write_nullw, mem_write_nulll,
|
||||
rom + ((i << 14) & biosmask),
|
||||
MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL);
|
||||
mem_mapping_disable(&dev->romcs_mapping[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
mem_mapping_add(&dev->bios_mapping[i], 0xe0000 + (i << 14), 0x4000,
|
||||
mem_read_bios, mem_read_biosw, mem_read_biosl,
|
||||
mem_write_null, mem_write_nullw, mem_write_nulll,
|
||||
rom + ((i << 14) & biosmask),
|
||||
MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL);
|
||||
if (i < 4)
|
||||
mem_mapping_disable(&dev->bios_mapping[i]);
|
||||
}
|
||||
|
||||
if (sx) {
|
||||
for (i = 24; i < 32; i++) {
|
||||
dev->page[i].valid = 1;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* 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 WD76C10 System Controller chip.
|
||||
*
|
||||
* Version: @(#)wd76c10.c 1.0.0 2019/05/14
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../io.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../mem.h"
|
||||
#include "../port_92.h"
|
||||
#include "../serial.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../video/vid_paradise.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
|
||||
uint16_t reg_0092;
|
||||
uint16_t reg_2072;
|
||||
uint16_t reg_2872;
|
||||
uint16_t reg_5872;
|
||||
|
||||
serial_t *uart[2];
|
||||
|
||||
fdc_t *fdc;
|
||||
} wd76c10_t;
|
||||
|
||||
|
||||
static uint16_t
|
||||
wd76c10_read(uint16_t port, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
int16_t ret = 0xffff;
|
||||
|
||||
switch (port) {
|
||||
case 0x2072:
|
||||
ret = dev->reg_2072;
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
ret = dev->reg_2872;
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
ret = dev->reg_5872;
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_write(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x2072:
|
||||
dev->reg_2072 = val;
|
||||
|
||||
serial_remove(dev->uart[0]);
|
||||
if (!(val & 0x10))
|
||||
{
|
||||
switch ((val >> 5) & 7)
|
||||
{
|
||||
case 1: serial_setup(dev->uart[0], 0x3f8, 4); break;
|
||||
case 2: serial_setup(dev->uart[0], 0x2f8, 4); break;
|
||||
case 3: serial_setup(dev->uart[0], 0x3e8, 4); break;
|
||||
case 4: serial_setup(dev->uart[0], 0x2e8, 4); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
serial_remove(dev->uart[1]);
|
||||
if (!(val & 0x01))
|
||||
{
|
||||
switch ((val >> 1) & 7)
|
||||
{
|
||||
case 1: serial_setup(dev->uart[1], 0x3f8, 3); break;
|
||||
case 2: serial_setup(dev->uart[1], 0x2f8, 3); break;
|
||||
case 3: serial_setup(dev->uart[1], 0x3e8, 3); break;
|
||||
case 4: serial_setup(dev->uart[1], 0x2e8, 3); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
dev->reg_2872 = val;
|
||||
|
||||
fdc_remove(dev->fdc);
|
||||
if (! (val & 1))
|
||||
fdc_set_base(dev->fdc, 0x03f0);
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
dev->reg_5872 = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
wd76c10_readb(uint16_t port, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
return(wd76c10_read(port & ~1, priv) >> 8);
|
||||
|
||||
return(wd76c10_read(port, priv) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_writeb(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t temp = wd76c10_read(port, priv);
|
||||
|
||||
if (port & 1)
|
||||
wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv);
|
||||
else
|
||||
wd76c10_write(port , (temp & 0xff00) | val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_close(void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
wd76c10_init(const device_t *info)
|
||||
{
|
||||
wd76c10_t *dev;
|
||||
|
||||
dev = (wd76c10_t *) malloc(sizeof(wd76c10_t));
|
||||
memset(dev, 0x00, sizeof(wd76c10_t));
|
||||
dev->type = info->local;
|
||||
|
||||
dev->fdc = (fdc_t *)device_add(&fdc_at_device);
|
||||
|
||||
dev->uart[0] = device_add_inst(&i8250_device, 1);
|
||||
dev->uart[1] = device_add_inst(&i8250_device, 2);
|
||||
|
||||
device_add(&port_92_word_device);
|
||||
|
||||
io_sethandler(0x2072, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0x2872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0x5872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t wd76c10_device = {
|
||||
"WD 76C10",
|
||||
0,
|
||||
0,
|
||||
wd76c10_init, wd76c10_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
Reference in New Issue
Block a user