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:
OBattler
2021-09-25 15:30:06 +02:00
parent b5f7e9bec3
commit 5ad606a8f2
8 changed files with 304 additions and 252 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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