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:
OBattler
2019-09-28 17:32:05 +02:00
parent b1f91ff54a
commit 6627282efb
13 changed files with 147 additions and 1943 deletions

View File

@@ -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

View File

@@ -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
};