From 5ad606a8f27b6af8cd99f9eafb1363c40f245fd1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 25 Sep 2021 15:30:06 +0200 Subject: [PATCH] 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. --- src/chipset/sis_85c4xx.c | 244 +++++++++++++++------------------------ src/chipset/sis_85c50x.c | 2 +- src/chipset/umc_8886.c | 6 + src/chipset/umc_hb4.c | 166 +++++++++++++++++++++----- src/cpu/386_common.c | 2 +- src/cpu/x86.c | 7 +- src/device/keyboard_at.c | 54 ++++----- src/mem/mem.c | 75 +++++------- 8 files changed, 304 insertions(+), 252 deletions(-) diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 0a2bf34af..4ca0c76d7 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -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 }; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index c01690064..84ad90c91 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -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(); } diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index a8962030b..591805329 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -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); } diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index b3d5cb0dc..d147bf5f7 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -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); diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 467ea01eb..4eb9530ba 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -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) { diff --git a/src/cpu/x86.c b/src/cpu/x86.c index c16939559..725d674e8 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -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; diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index c64f8b87f..5dc67ad55 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -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; } diff --git a/src/mem/mem.c b/src/mem/mem.c index 693f9db2a..855cdd93a 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -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;