UMC HB4 shadow RAM overhaul and SMRAM fixes, slight changes to SiS 85c4xx, a fix for SiS 85c50x, fixed SMBASE on 486 (it should *NOT* zero the most significant 8 bits!), various improvements to mem.c (eg. mem_invalidate_range() is now faster), fixed resetting PCI on soft reset, and made the KBC soft reset again.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
@@ -39,6 +40,7 @@ typedef struct
|
||||
reg_base, reg_last,
|
||||
reg_00, is_471,
|
||||
regs[39], scratch[2];
|
||||
uint32_t mem_state[8];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
} sis_85c4xx_t;
|
||||
@@ -47,7 +49,7 @@ typedef struct
|
||||
static void
|
||||
sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t base, n = 0;
|
||||
uint32_t i, shflags = 0;
|
||||
uint32_t readext, writeext;
|
||||
uint8_t romcs = 0xc0, cur_romcs;
|
||||
@@ -73,12 +75,25 @@ sis_85c4xx_recalcmapping(sis_85c4xx_t *dev)
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : readext;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? writeext : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state(base, 0x8000, readext | writeext);
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
if ((base >= 0xf0000) && (dev->mem_state[i] & MEM_READ_INTERNAL) && !(shflags & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(base, base + 0x7fff);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
} else {
|
||||
shflags = readext | writeext;
|
||||
if (dev->mem_state[i] != shflags) {
|
||||
n++;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
dev->mem_state[i] = shflags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +156,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case 0x02: case 0x03:
|
||||
case 0x08:
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
if (valxor)
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
@@ -237,6 +253,69 @@ sis_85c4xx_in(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_reset(void *priv)
|
||||
{
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) priv;
|
||||
int mem_size_mb = mem_size >> 10;
|
||||
static uint8_t ram_4xx[64] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
||||
0x19, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x04, 0x04, 0x05, 0x05, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x13, 0x21, 0x06, 0x06, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
|
||||
0x1b, 0x1b, 0x1b, 0x1b, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
|
||||
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e };
|
||||
|
||||
memset(dev->regs, 0x00, sizeof(dev->regs));
|
||||
|
||||
if (cpu_s->rspeed < 25000000)
|
||||
dev->regs[0x08] = 0x80;
|
||||
|
||||
if (dev->is_471) {
|
||||
dev->regs[0x09] = 0x40;
|
||||
if (mem_size_mb >= 64) {
|
||||
if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[0x09] |= 0x22;
|
||||
else
|
||||
dev->regs[0x09] |= 0x24;
|
||||
} else
|
||||
dev->regs[0x09] |= ram_471[mem_size_mb];
|
||||
|
||||
dev->regs[0x11] = 0x09;
|
||||
dev->regs[0x12] = 0xff;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xf0;
|
||||
dev->regs[0x26] = 0x01;
|
||||
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1);
|
||||
|
||||
port_92_remove(dev->port_92);
|
||||
|
||||
mem_remap_top(256);
|
||||
soft_reset_mask = 0;
|
||||
} else {
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
if (dev->reg_base == 0x60)
|
||||
dev->reg_00 = 0x24;
|
||||
|
||||
if (mem_size_mb == 64)
|
||||
dev->regs[0x00] = 0x1f;
|
||||
else if (mem_size_mb < 64)
|
||||
dev->regs[0x00] = ram_4xx[mem_size_mb];
|
||||
|
||||
dev->regs[0x11] = 0x01;
|
||||
}
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c4xx_close(void *priv)
|
||||
{
|
||||
@@ -252,8 +331,6 @@ sis_85c4xx_close(void *priv)
|
||||
static void *
|
||||
sis_85c4xx_init(const device_t *info)
|
||||
{
|
||||
int mem_size_mb;
|
||||
|
||||
sis_85c4xx_t *dev = (sis_85c4xx_t *) malloc(sizeof(sis_85c4xx_t));
|
||||
memset(dev, 0, sizeof(sis_85c4xx_t));
|
||||
|
||||
@@ -261,161 +338,22 @@ sis_85c4xx_init(const device_t *info)
|
||||
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
mem_size_mb = mem_size >> 10;
|
||||
|
||||
if (cpu_s->rspeed < 25000000)
|
||||
dev->regs[0x08] = 0x80;
|
||||
|
||||
if (dev->is_471) {
|
||||
dev->reg_last = dev->reg_base + 0x76;
|
||||
|
||||
dev->regs[0x09] = 0x40;
|
||||
switch (mem_size_mb) {
|
||||
case 0: case 1:
|
||||
dev->regs[0x09] |= 0x00;
|
||||
break;
|
||||
case 2: case 3:
|
||||
dev->regs[0x09] |= 0x01;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[0x09] |= 0x02;
|
||||
break;
|
||||
case 5:
|
||||
dev->regs[0x09] |= 0x20;
|
||||
break;
|
||||
case 6: case 7:
|
||||
dev->regs[0x09] |= 0x09;
|
||||
break;
|
||||
case 8: case 9:
|
||||
dev->regs[0x09] |= 0x04;
|
||||
break;
|
||||
case 10: case 11:
|
||||
dev->regs[0x09] |= 0x05;
|
||||
break;
|
||||
case 12: case 13: case 14: case 15:
|
||||
dev->regs[0x09] |= 0x0b;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[0x09] |= 0x13;
|
||||
break;
|
||||
case 17:
|
||||
dev->regs[0x09] |= 0x21;
|
||||
break;
|
||||
case 18: case 19:
|
||||
dev->regs[0x09] |= 0x06;
|
||||
break;
|
||||
case 20: case 21: case 22: case 23:
|
||||
dev->regs[0x09] |= 0x0d;
|
||||
break;
|
||||
case 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
dev->regs[0x09] |= 0x0e;
|
||||
break;
|
||||
case 32: case 33: case 34: case 35:
|
||||
dev->regs[0x09] |= 0x1b;
|
||||
break;
|
||||
case 36: case 37: case 38: case 39:
|
||||
dev->regs[0x09] |= 0x0f;
|
||||
break;
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
dev->regs[0x09] |= 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[0x09] |= 0x1e;
|
||||
break;
|
||||
default:
|
||||
if (mem_size_mb < 64)
|
||||
dev->regs[0x09] |= 0x1e;
|
||||
else if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[0x09] |= 0x22;
|
||||
else
|
||||
dev->regs[0x09] |= 0x24;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 0x09;
|
||||
dev->regs[0x12] = 0xff;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xf0;
|
||||
dev->regs[0x26] = 0x01;
|
||||
|
||||
dev->smram = smram_add();
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x00010000, 0, 1);
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
port_92_remove(dev->port_92);
|
||||
} else {
|
||||
} else
|
||||
dev->reg_last = dev->reg_base + 0x11;
|
||||
|
||||
/* Bits 6 and 7 must be clear on the SiS 40x. */
|
||||
if (dev->reg_base == 0x60)
|
||||
dev->reg_00 = 0x24;
|
||||
|
||||
switch (mem_size_mb) {
|
||||
case 1:
|
||||
default:
|
||||
dev->regs[0x00] = 0x00;
|
||||
break;
|
||||
case 2:
|
||||
dev->regs[0x00] = 0x01;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[0x00] = 0x02;
|
||||
break;
|
||||
case 6:
|
||||
dev->regs[0x00] = 0x03;
|
||||
break;
|
||||
case 8:
|
||||
dev->regs[0x00] = 0x04;
|
||||
break;
|
||||
case 10:
|
||||
dev->regs[0x00] = 0x05;
|
||||
break;
|
||||
case 12:
|
||||
dev->regs[0x00] = 0x0b;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[0x00] = 0x19;
|
||||
break;
|
||||
case 18:
|
||||
dev->regs[0x00] = 0x06;
|
||||
break;
|
||||
case 20:
|
||||
dev->regs[0x00] = 0x14;
|
||||
break;
|
||||
case 24:
|
||||
dev->regs[0x00] = 0x15;
|
||||
break;
|
||||
case 32:
|
||||
dev->regs[0x00] = 0x1b;
|
||||
break;
|
||||
case 36:
|
||||
dev->regs[0x00] = 0x16;
|
||||
break;
|
||||
case 40:
|
||||
dev->regs[0x00] = 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[0x00] = 0x1e;
|
||||
break;
|
||||
case 64:
|
||||
dev->regs[0x00] = 0x1f;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 0x01;
|
||||
}
|
||||
|
||||
io_sethandler(0x0022, 0x0002,
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
io_sethandler(0x00e1, 0x0002,
|
||||
sis_85c4xx_in, NULL, NULL, sis_85c4xx_out, NULL, NULL, dev);
|
||||
|
||||
sis_85c4xx_recalcmapping(dev);
|
||||
sis_85c4xx_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -425,7 +363,7 @@ const device_t sis_85c401_device = {
|
||||
"SiS 85c401/85c402",
|
||||
0,
|
||||
0x060,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -434,7 +372,7 @@ const device_t sis_85c460_device = {
|
||||
"SiS 85c460",
|
||||
0,
|
||||
0x050,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -444,7 +382,7 @@ const device_t sis_85c461_device = {
|
||||
"SiS 85c461",
|
||||
0,
|
||||
0x050,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -453,7 +391,7 @@ const device_t sis_85c471_device = {
|
||||
"SiS 85c407/85c471",
|
||||
0,
|
||||
0x150,
|
||||
sis_85c4xx_init, sis_85c4xx_close, NULL,
|
||||
sis_85c4xx_init, sis_85c4xx_close, sis_85c4xx_reset,
|
||||
{ NULL }, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
@@ -89,7 +89,7 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -291,6 +291,9 @@ umc_8886_reset(void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *)priv;
|
||||
|
||||
memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0]));
|
||||
memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1]));
|
||||
|
||||
dev->pci_conf_sb[0][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[0][1] = 0x10;
|
||||
|
||||
@@ -336,6 +339,9 @@ umc_8886_reset(void *priv)
|
||||
|
||||
for (int i = 1; i < 5; i++) /* Disable all IRQ interrupts */
|
||||
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
|
||||
|
||||
cpu_set_isa_pci_div(3);
|
||||
cpu_set_pci_speed(cpu_busspeed / 2);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -97,6 +97,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
@@ -106,6 +107,18 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen_public.h"
|
||||
#else
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define PAGE_MASK_SHIFT 6
|
||||
#else
|
||||
# define PAGE_MASK_INDEX_MASK 3
|
||||
# define PAGE_MASK_INDEX_SHIFT 10
|
||||
# define PAGE_MASK_SHIFT 4
|
||||
#endif
|
||||
# define PAGE_MASK_MASK 63
|
||||
#endif
|
||||
#include <86box/chipset.h>
|
||||
|
||||
|
||||
@@ -131,34 +144,108 @@ hb4_log(const char *fmt, ...)
|
||||
|
||||
typedef struct hb4_t
|
||||
{
|
||||
uint8_t pci_conf[128]; /* PCI Registers */
|
||||
smram_t *smram; /* SMRAM Handler */
|
||||
uint8_t shadow,
|
||||
shadow_read, shadow_write,
|
||||
pci_conf[256]; /* PCI Registers */
|
||||
int mem_state[9];
|
||||
smram_t *smram[2]; /* SMRAM Handlers */
|
||||
} hb4_t;
|
||||
|
||||
|
||||
static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY),
|
||||
(MEM_READ_INTERNAL | MEM_WRITE_INTERNAL), (MEM_READ_INTERNAL | MEM_WRITE_EXTANY) };
|
||||
static int shadow_read[2] = { MEM_READ_EXTANY, MEM_READ_INTERNAL };
|
||||
static int shadow_write[2] = { MEM_WRITE_INTERNAL, MEM_WRITE_EXTANY };
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_bios_high(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_bios[dev->pci_conf[0x55] >> 6];
|
||||
|
||||
if (state != dev->mem_state[8]) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
if ((dev->mem_state[8] & MEM_READ_INTERNAL) && !(state & MEM_READ_INTERNAL))
|
||||
mem_invalidate_range(0xf0000, 0xfffff);
|
||||
dev->mem_state[8] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_bios_low(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)];
|
||||
|
||||
if (state != dev->mem_state[7]) {
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, state);
|
||||
dev->mem_state[7] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_main(hb4_t *dev)
|
||||
{
|
||||
int i, state;
|
||||
int n = 0;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[i + 1]) {
|
||||
n++;
|
||||
mem_set_mem_state_both(0xc8000 + (i << 14), 0x4000, state);
|
||||
dev->mem_state[i + 1] = state;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hb4_shadow_video(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[0]) {
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, state);
|
||||
dev->mem_state[0] = state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb4_shadow(hb4_t *dev)
|
||||
{
|
||||
int state, i;
|
||||
int n = 0;
|
||||
pclog("SHADOW: %02X%02X\n", dev->pci_conf[0x55], dev->pci_conf[0x54]);
|
||||
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, ((dev->pci_conf[0x55] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) |
|
||||
((dev->pci_conf[0x55] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL));
|
||||
n = hb4_shadow_bios_high(dev);
|
||||
n += hb4_shadow_bios_low(dev);
|
||||
n += hb4_shadow_main(dev);
|
||||
n += hb4_shadow_video(dev);
|
||||
|
||||
if (dev->pci_conf[0x54] & 1) {
|
||||
state = (dev->pci_conf[0x54] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[0x55] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, state);
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
state = (dev->pci_conf[0x54] & (1 << (i + 2))) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[0x55] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
|
||||
mem_set_mem_state_both(0xc8000 + (i << 4), 0x4000, state);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
if (n > 0)
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +256,9 @@ hb4_smram(hb4_t *dev)
|
||||
|
||||
/* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled
|
||||
in SMM, and is always set to A0000-BFFFF. */
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
/* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */
|
||||
smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
|
||||
/* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses
|
||||
this. */
|
||||
@@ -185,6 +274,8 @@ static void
|
||||
hb4_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
uint8_t old;
|
||||
|
||||
hb4_log("UM8881: dev->regs[%02x] = %02x POST: %02x \n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
@@ -207,11 +298,23 @@ hb4_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x51: case 0x52:
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x54: case 0x55:
|
||||
case 0x53:
|
||||
old = dev->pci_conf[addr];
|
||||
dev->pci_conf[addr] = val;
|
||||
pclog("HB53: %02X\n", val);
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->shadow_read = (val & 0x80);
|
||||
dev->shadow_write = (val & 0x40);
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
case 0x54:
|
||||
dev->shadow = (val & 0x01) << 1;
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
@@ -236,8 +339,12 @@ static uint8_t
|
||||
hb4_read(int func, int addr, void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
return dev->pci_conf[addr];
|
||||
if (func == 0)
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -245,6 +352,7 @@ static void
|
||||
hb4_reset(void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *)priv;
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
|
||||
dev->pci_conf[0] = 0x60; /* UMC */
|
||||
dev->pci_conf[1] = 0x10;
|
||||
@@ -269,7 +377,12 @@ hb4_reset(void *priv)
|
||||
|
||||
hb4_write(0, 0x54, 0x00, dev);
|
||||
hb4_write(0, 0x55, 0x00, dev);
|
||||
hb4_write(0, 0x60, 0x20, dev);
|
||||
hb4_write(0, 0x60, 0x80, dev);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
memset(dev->mem_state, 0x00, sizeof(dev->mem_state));
|
||||
}
|
||||
|
||||
|
||||
@@ -294,7 +407,8 @@ hb4_init(const device_t *info)
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
|
||||
hb4_reset(dev);
|
||||
|
||||
|
@@ -591,7 +591,7 @@ smram_restore_state_p5(uint32_t *saved_state)
|
||||
smm_seg_load(&cpu_state.seg_gs);
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||
smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] & 0x00ffffff;
|
||||
smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET];
|
||||
|
||||
/* Am486/5x86 stuff */
|
||||
if (!is_pentium) {
|
||||
|
@@ -241,8 +241,13 @@ reset_common(int hard)
|
||||
leave_smm();
|
||||
|
||||
/* Needed for the ALi M1533. */
|
||||
if (is486 && (hard || soft_reset_pci))
|
||||
if (is486 && (hard || soft_reset_pci)) {
|
||||
pci_reset();
|
||||
if (!hard && soft_reset_pci) {
|
||||
dma_reset();
|
||||
device_reset_all();
|
||||
}
|
||||
}
|
||||
|
||||
use32 = 0;
|
||||
cpu_cur_status = 0;
|
||||
|
@@ -673,6 +673,7 @@ kbd_status(const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
// #define ENABLE_KEYBOARD_AT_LOG 1
|
||||
#ifdef ENABLE_KEYBOARD_AT_LOG
|
||||
int keyboard_at_do_log = ENABLE_KEYBOARD_AT_LOG;
|
||||
|
||||
@@ -1219,13 +1220,14 @@ write_output(atkbd_t *dev, uint8_t val)
|
||||
/* Do this here to avoid an infinite reset loop. */
|
||||
dev->p2 = val;
|
||||
|
||||
/* 0 holds the CPU in the RESET state, 1 releases it. To simply this,
|
||||
/* 0 holds the CPU in the RESET state, 1 releases it. To simplify this,
|
||||
we just do everything on release. */
|
||||
if ((val & 0x01) && !(old & 0x01)) {
|
||||
if (val & 0x01) {
|
||||
/* Pin 0 selected. */
|
||||
pclog("write_output(): Pulse reset!\n");
|
||||
hardresetx86(); /*Pulse reset!*/
|
||||
softresetx86(); /*Pulse reset!*/
|
||||
cpu_set_edx();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2936,18 +2938,36 @@ static void
|
||||
kbd_reset(void *priv)
|
||||
{
|
||||
atkbd_t *dev = (atkbd_t *)priv;
|
||||
int i;
|
||||
uint8_t kbc_ven;
|
||||
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
||||
kbc_ven = dev->flags & KBC_VEN_MASK;
|
||||
|
||||
dev->status &= ~(STAT_IFULL | STAT_OFULL | STAT_CD);
|
||||
dev->last_irq = 0;
|
||||
picintc(1 << 1);
|
||||
picintc(1 << 12);
|
||||
dev->secr_phase = 0;
|
||||
dev->kbd_in = 0;
|
||||
dev->ob = 0xff;
|
||||
|
||||
sc_or = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
kbd_power_on(atkbd_t *dev)
|
||||
{
|
||||
int i;
|
||||
uint8_t kbc_ven = dev->flags & KBC_VEN_MASK;
|
||||
|
||||
kbd_reset(dev);
|
||||
|
||||
dev->status = STAT_UNLOCKED;
|
||||
/* Write the value here first, so that we don't hit a pulse reset. */
|
||||
dev->p2 = 0xcf;
|
||||
write_output(dev, 0xcf);
|
||||
dev->mem[0x20] = 0x01;
|
||||
dev->mem[0x20] |= CCB_TRANSLATE;
|
||||
dev->ami_mode = !!(dev->flags & KBC_FLAG_PS2);
|
||||
|
||||
/* Set up the correct Video Type bits. */
|
||||
@@ -2960,17 +2980,15 @@ kbd_reset(void *priv)
|
||||
dev->inhibit = 0x10;
|
||||
kbd_log("ATkbc: input port = %02x\n", dev->p1);
|
||||
|
||||
keyboard_mode = 0x02 | (dev->mem[0x20] & CCB_TRANSLATE);
|
||||
|
||||
/* Enable keyboard, disable mouse. */
|
||||
set_enable_kbd(dev, 1);
|
||||
keyboard_scan = 1;
|
||||
set_enable_mouse(dev, 0);
|
||||
mouse_scan = 0;
|
||||
|
||||
dev->ob = 0xff;
|
||||
dev->mem[0x31] = 0xfe;
|
||||
|
||||
sc_or = 0;
|
||||
keyboard_mode = 0x02 | (dev->mem[0x20] & CCB_TRANSLATE);
|
||||
|
||||
for (i = 1; i <= 2; i++)
|
||||
kbc_queue_reset(i);
|
||||
@@ -2978,22 +2996,6 @@ kbd_reset(void *priv)
|
||||
memset(keyboard_set3_flags, 0, 512);
|
||||
|
||||
set_scancode_map(dev);
|
||||
|
||||
dev->mem[0x31] = 0xfe;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
kbd_power_on(atkbd_t *dev)
|
||||
{
|
||||
kbd_reset(dev);
|
||||
|
||||
dev->status = STAT_UNLOCKED;
|
||||
/* Write the value here first, so that we don't hit a pulse reset. */
|
||||
dev->p2 = 0xcf;
|
||||
write_output(dev, 0xcf);
|
||||
dev->mem[0x20] = 0x01;
|
||||
dev->mem[0x20] |= CCB_TRANSLATE;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1913,13 +1913,13 @@ page_remove_from_evict_list(page_t *p)
|
||||
void
|
||||
mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
|
||||
{
|
||||
if ((p != NULL) && (p->mem == page_ff))
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
if (val != p->mem[addr & 0xfff] || codegen_in_recompile) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
#else
|
||||
if (val != p->mem[addr & 0xfff]) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) {
|
||||
#endif
|
||||
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
|
||||
@@ -1939,13 +1939,13 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
|
||||
void
|
||||
mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
|
||||
{
|
||||
if ((p != NULL) && (p->mem == page_ff))
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
#else
|
||||
if (val != *(uint16_t *)&p->mem[addr & 0xfff]) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff])) {
|
||||
#endif
|
||||
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
|
||||
@@ -1975,13 +1975,13 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
|
||||
void
|
||||
mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
|
||||
{
|
||||
if ((p != NULL) && (p->mem == page_ff))
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
#else
|
||||
if (val != *(uint32_t *)&p->mem[addr & 0xfff]) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff])) {
|
||||
#endif
|
||||
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
|
||||
@@ -2007,13 +2007,13 @@ mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
|
||||
void
|
||||
mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
|
||||
{
|
||||
if ((p != NULL) && (p->mem == page_ff))
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
if ((p == NULL) || (p->mem == NULL) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
#else
|
||||
if ((p == NULL) || (p->mem == NULL) || (val != p->mem[addr & 0xfff])) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != p->mem[addr & 0xfff])) {
|
||||
#endif
|
||||
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
|
||||
@@ -2025,13 +2025,13 @@ mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p)
|
||||
void
|
||||
mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
|
||||
{
|
||||
if ((p != NULL) && (p->mem == page_ff))
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
if ((p == NULL) || (p->mem == NULL) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
#else
|
||||
if ((p == NULL) || (p->mem == NULL) || (val != *(uint16_t *)&p->mem[addr & 0xfff])) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint16_t *)&p->mem[addr & 0xfff])) {
|
||||
#endif
|
||||
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
if ((addr & 0xf) == 0xf)
|
||||
@@ -2045,13 +2045,13 @@ mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p)
|
||||
void
|
||||
mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p)
|
||||
{
|
||||
if ((p != NULL) && (p->mem == page_ff))
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
if ((p == NULL) || (p->mem == NULL) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff]) || codegen_in_recompile) {
|
||||
#else
|
||||
if ((p == NULL) || (p->mem == NULL) || (val != *(uint32_t *)&p->mem[addr & 0xfff])) {
|
||||
if ((p->mem == NULL) || (p->mem == page_ff) || (val != *(uint32_t *)&p->mem[addr & 0xfff])) {
|
||||
#endif
|
||||
uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
if ((addr & 0xf) >= 0xd)
|
||||
@@ -2180,42 +2180,27 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv)
|
||||
void
|
||||
mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
|
||||
{
|
||||
uint64_t mask;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
int byte_offset;
|
||||
uint64_t byte_mask;
|
||||
uint32_t i;
|
||||
page_t *p;
|
||||
|
||||
start_addr &= ~PAGE_MASK_MASK;
|
||||
end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK;
|
||||
|
||||
for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) {
|
||||
for (; start_addr <= end_addr; start_addr += 0x1000) {
|
||||
if ((start_addr >> 12) >= pages_sz)
|
||||
continue;
|
||||
|
||||
mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
|
||||
p = &pages[start_addr >> 12];
|
||||
p->dirty_mask |= mask;
|
||||
if ((p->code_present_mask & mask) && !page_in_evict_list(p))
|
||||
page_add_to_evict_list(p);
|
||||
if (p) {
|
||||
p->dirty_mask = 0xffffffffffffffffULL;
|
||||
|
||||
for (i = start_addr; (i <= end_addr) && (i < (start_addr + (1 << PAGE_MASK_SHIFT))); i++) {
|
||||
/* Do not look at the byte stuff if start_addr >= (mem_size * 1024), as we do not allocate the
|
||||
byte dirty and code present mask arrays beyond the end of RAM. */
|
||||
if (i < (mem_size << 10)) {
|
||||
byte_offset = (i >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
|
||||
byte_mask = (uint64_t)1 << (i & PAGE_BYTE_MASK_MASK);
|
||||
if (p->byte_dirty_mask)
|
||||
memset(p->byte_dirty_mask, 0xff, 64 * sizeof(uint64_t));
|
||||
|
||||
if (p) {
|
||||
if (p->byte_dirty_mask)
|
||||
p->byte_dirty_mask[byte_offset] |= byte_mask;
|
||||
if (p->byte_code_present_mask && (p->byte_code_present_mask[byte_offset] & byte_mask) &&
|
||||
!page_in_evict_list(p))
|
||||
page_add_to_evict_list(p);
|
||||
}
|
||||
}
|
||||
if (!page_in_evict_list(p))
|
||||
page_add_to_evict_list(p);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -2223,14 +2208,12 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
|
||||
start_addr &= ~PAGE_MASK_MASK;
|
||||
end_addr = (end_addr + PAGE_MASK_MASK) & ~PAGE_MASK_MASK;
|
||||
|
||||
for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) {
|
||||
mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
|
||||
for (; start_addr <= end_addr; start_addr += 0x1000) {
|
||||
/* Do nothing if the pages array is empty or DMA reads/writes to/from PCI device memory addresses
|
||||
may crash the emulator. */
|
||||
cur_addr = (start_addr >> 12);
|
||||
if (cur_addr < pages_sz)
|
||||
pages[cur_addr].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask;
|
||||
memset(pages[cur_addr].dirty_mask, 0xff, sizeof(pages[cur_addr].dirty_mask));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2712,6 +2695,7 @@ mem_reset(void)
|
||||
if ((c << 12) >= (mem_size << 10))
|
||||
pages[c].mem = page_ff;
|
||||
else {
|
||||
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
|
||||
if (mem_size > 1048576) {
|
||||
if ((c << 12) < (1 << 30))
|
||||
pages[c].mem = &ram[c << 12];
|
||||
@@ -2719,6 +2703,9 @@ mem_reset(void)
|
||||
pages[c].mem = &ram2[(c << 12) - (1 << 30)];
|
||||
} else
|
||||
pages[c].mem = &ram[c << 12];
|
||||
#else
|
||||
pages[c].mem = &ram[c << 12];
|
||||
#endif
|
||||
}
|
||||
if (c < m) {
|
||||
pages[c].write_b = mem_write_ramb_page;
|
||||
|
Reference in New Issue
Block a user