diff --git a/src/chipset/scat.c b/src/chipset/scat.c index a1bbca168..0965c991e 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -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; diff --git a/src/chipset/scat_varcem.c b/src/chipset/scat_varcem.c deleted file mode 100644 index fb0e6bf80..000000000 --- a/src/chipset/scat_varcem.c +++ /dev/null @@ -1,1642 +0,0 @@ -/* - * VARCem Virtual ARchaeological Computer EMulator. - * An emulator of (mostly) x86-based PC systems and devices, - * using the ISA,EISA,VLB,MCA and PCI system buses, roughly - * spanning the era between 1981 and 1995. - * - * This file is part of the VARCem Project. - * - * Implementation of the C&T 82C235 ("SCAT") chipset. - * - * Version: @(#)scat.c 1.0.18 2019/05/13 - * - * Authors: Fred N. van Kempen, - * Original by GreatPsycho for PCem. - * Miran Grca, - * - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the: - * - * Free Software Foundation, Inc. - * 59 Temple Place - Suite 330 - * Boston, MA 02111-1307 - * USA. - */ -#include -#include -#include -#include -#include -#include "../../emu.h" -#include "../../config.h" -#include "../../cpu/cpu.h" -#include "../../cpu/x86.h" -#include "../../io.h" -#include "../../mem.h" -#include "../../rom.h" -#include "../../device.h" -#include "../../plat.h" -#include "../system/nmi.h" -#include "scat.h" - - -#define SCAT_DMA_WAIT_STATE_CONTROL 0x01 -#define SCAT_VERSION 0x40 -#define SCAT_CLOCK_CONTROL 0x41 -#define SCAT_PERIPHERAL_CONTROL 0x44 -#define SCAT_MISCELLANEOUS_STATUS 0x45 -#define SCAT_POWER_MANAGEMENT 0x46 -#define SCAT_ROM_ENABLE 0x48 -#define SCAT_RAM_WRITE_PROTECT 0x49 -#define SCAT_SHADOW_RAM_ENABLE_1 0x4A -#define SCAT_SHADOW_RAM_ENABLE_2 0x4B -#define SCAT_SHADOW_RAM_ENABLE_3 0x4C -#define SCAT_DRAM_CONFIGURATION 0x4D -#define SCAT_EXTENDED_BOUNDARY 0x4E -#define SCAT_EMS_CONTROL 0x4F - -#define SCATSX_LAPTOP_FEATURES 0x60 -#define SCATSX_FAST_VIDEO_CONTROL 0x61 -#define SCATSX_FAST_VIDEORAM_ENABLE 0x62 -#define SCATSX_HIGH_PERFORMANCE_REFRESH 0x63 -#define SCATSX_CAS_TIMING_FOR_DMA 0x64 - - -typedef struct { - uint8_t regs_2x8; - uint8_t regs_2x9; -} ems_page_t; - -typedef struct { - int type; - - int indx; - uint8_t regs[256]; - uint8_t reg_2xA; - uint8_t port_92; - - uint32_t xms_bound; - - int external_is_RAS; - - ems_page_t page[32]; - - mem_mapping_t low_mapping[32]; - 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 ems_mapping[32]; -} scat_t; - - -static const uint8_t max_map[32] = { - 0, 1, 1, 1, 2, 3, 4, 8, - 4, 8, 12, 16, 20, 24, 28, 32, - 0, 5, 9, 13, 6, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; -static const uint8_t max_map_sx[32] = { - 0, 1, 2, 1, 3, 4, 6, 10, - 5, 9, 13, 4, 8, 12, 16, 14, - 18, 22, 26, 20, 24, 28, 32, 18, - 20, 32, 0, 0, 0, 0, 0, 0 -}; -static const uint8_t scatsx_external_is_RAS[33] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0 -}; - - -static uint8_t scat_read(uint16_t port, priv_t priv); -static void scat_write(uint16_t port, uint8_t val, priv_t 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(&bios_mapping[i << 1]); - mem_mapping_enable(&bios_mapping[(i << 1) + 1]); - } else { - mem_mapping_disable(&bios_mapping[i << 1]); - mem_mapping_disable(&bios_mapping[(i << 1) + 1]); - } - val >>= 1; - } -} - - -static void -shadow_state_update(scat_t *dev) -{ - int i, val; - - 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); - } - - flushmmucache(); -} - - -static void -set_xms_bound(scat_t *dev, uint8_t val) -{ - uint32_t xms_max = ((dev->regs[SCAT_VERSION] & 0xf0) != 0 && ((val & 0x10) != 0)) || (dev->regs[SCAT_VERSION] >= 4) ? 0xfe0000 : 0xfc0000; - int i; - - switch (val & 0x0f) { - case 1: - dev->xms_bound = 0x100000; - break; - - case 2: - dev->xms_bound = 0x140000; - break; - - case 3: - dev->xms_bound = 0x180000; - break; - - case 4: - dev->xms_bound = 0x200000; - break; - - case 5: - dev->xms_bound = 0x300000; - break; - - case 6: - dev->xms_bound = 0x400000; - break; - - case 7: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0x600000 : 0x500000; - break; - - case 8: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0x800000 : 0x700000; - break; - - case 9: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0xa00000 : 0x800000; - break; - - case 10: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0xc00000 : 0x900000; - break; - - case 11: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0xe00000 : 0xa00000; - break; - - case 12: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? xms_max : 0xb00000; - break; - - case 13: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? xms_max : 0xc00000; - break; - - case 14: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? xms_max : 0xd00000; - break; - - case 15: - dev->xms_bound = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? xms_max : 0xf00000; - break; - - default: - dev->xms_bound = xms_max; - break; - } - - if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && (val & 0x40) == 0 && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) == 3) || - (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3)) { - if ((val & 0x0f) == 0 || dev->xms_bound > 0x160000) - dev->xms_bound = 0x160000; - - if (dev->xms_bound > 0x100000) - mem_set_mem_state(0x100000, dev->xms_bound - 0x100000, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - - if (dev->xms_bound < 0x160000) - mem_set_mem_state(dev->xms_bound, 0x160000 - dev->xms_bound, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } else { - if (dev->xms_bound > xms_max) - dev->xms_bound = xms_max; - - if (dev->xms_bound > 0x100000) - mem_set_mem_state(0x100000, dev->xms_bound - 0x100000, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - - if (dev->xms_bound < ((uint32_t)mem_size << 10)) - mem_set_mem_state(dev->xms_bound, (mem_size << 10) - dev->xms_bound, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - - mem_mapping_set_addr(&dev->low_mapping[31], 0xf80000, - ((dev->regs[SCAT_VERSION] & 0xf0) != 0 && ((val & 0x10) != 0)) || - (dev->regs[SCAT_VERSION] >= 4) ? 0x60000 : 0x40000); - if (dev->regs[SCAT_VERSION] & 0xf0) { - for (i = 0; i < 8; i++) { - if (val & 0x10) - mem_mapping_disable(&dev->high_mapping[i]); - else - mem_mapping_enable(&dev->high_mapping[i]); - } - } -} - - -static uint32_t -get_addr(scat_t *dev, uint32_t addr, ems_page_t *p) -{ - int nbanks_2048k, nbanks_512k; - uint32_t addr2; - int nbank; - - if (p && (dev->regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) - addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; - - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) { - switch((dev->regs[SCAT_EXTENDED_BOUNDARY] & ((dev->regs[SCAT_VERSION] & 0x0f) > 3 ? 0x40 : 0)) | (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f)) { - case 0x41: - nbank = addr >> 19; - if (nbank < 4) - nbank = 1; - else if (nbank == 4) - nbank = 0; - else - nbank -= 3; - break; - - case 0x42: - nbank = addr >> 19; - if (nbank < 8) - nbank = 1 + (nbank >> 2); - else if (nbank == 8) - nbank = 0; - else - nbank -= 6; - break; - - case 0x43: - nbank = addr >> 19; - if (nbank < 12) - nbank = 1 + (nbank >> 2); - else if (nbank == 12) - nbank = 0; - else - nbank -= 9; - break; - - case 0x44: - nbank = addr >> 19; - if (nbank < 4) - nbank = 2; - else if (nbank < 6) - nbank -= 4; - else - nbank -= 3; - break; - - case 0x45: - nbank = addr >> 19; - if (nbank < 8) - nbank = 2 + (nbank >> 2); - else if (nbank < 10) - nbank -= 8; - else - nbank -= 6; - break; - - default: - nbank = addr >> (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) < 8 && (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) ? 19 : 21); - break; - } - - nbank &= (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; - - if ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && - (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) == 3 && - nbank == 2 && (addr & 0x7ffff) < 0x60000 && mem_size > 640) { - nbank = 1; - addr ^= 0x70000; - } - - if (dev->external_is_RAS && (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) { - if (nbank == 3) - nbank = 7; - else - return 0xffffffff; - } else if (!dev->external_is_RAS && dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80) { - switch(nbank) { - case 7: - nbank = 3; - break; - - /* Note - In the following cases, the chipset accesses multiple memory banks - at the same time, so it's impossible to predict which memory bank - is actually accessed. */ - case 5: - case 1: - nbank = 1; - break; - - case 3: - nbank = 2; - break; - - default: - nbank = 0; - break; - } - } - - if ((dev->regs[SCAT_VERSION] & 0x0f) > 3 && (mem_size > 2048) && (mem_size & 1536)) { - if ((mem_size & 1536) == 512) { - if (nbank == 0) - addr &= 0x7ffff; - else - addr = 0x80000 + ((addr & 0x1fffff) | ((nbank - 1) << 21)); - } else { - if (nbank < 2) - addr = (addr & 0x7ffff) | (nbank << 19); - else - addr = 0x100000 + ((addr & 0x1fffff) | ((nbank - 2) << 21)); - } - } else { - if (mem_size <= ((dev->regs[SCAT_VERSION] & 0x0f) > 3 ? 2048 : 4096) && (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) < 8) || dev->external_is_RAS)) { - nbanks_2048k = 0; - nbanks_512k = mem_size >> 9; - } else { - nbanks_2048k = mem_size >> 11; - nbanks_512k = (mem_size & 1536) >> 9; - } - - if (nbank < nbanks_2048k || (nbanks_2048k > 0 && nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7))) { - addr &= 0x1fffff; - addr |= (nbank << 21); - } else if (nbank < nbanks_2048k + nbanks_512k || nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7)) { - addr &= 0x7ffff; - addr |= (nbanks_2048k << 21) | ((nbank - nbanks_2048k) << 19); - } else { - addr &= 0x1ffff; - addr |= (nbanks_2048k << 21) | (nbanks_512k << 19) | ((nbank - nbanks_2048k - nbanks_512k) << 17); - } - } - } else { - switch(dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) { - case 0x02: - case 0x04: - nbank = addr >> 19; - if ((nbank & (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else - addr2 = addr >> 10; - break; - - case 0x03: - nbank = addr >> 19; - if ((nbank & (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if ((nbank & (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) == 2 && (addr & 0x7ffff) < 0x60000) { - addr ^= 0x1f0000; - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else - addr2 = addr >> 10; - break; - - case 0x05: - nbank = addr >> 19; - if ((nbank & (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) { - nbank = (addr >> 10) & 3; - addr2 = addr >> 12; - } else - addr2 = addr >> 10; - break; - - case 0x06: - nbank = addr >> 19; - if (nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else { - nbank = 2 + ((addr - 0x100000) >> 21); - addr2 = (addr - 0x100000) >> 11; - } - break; - - case 0x07: - case 0x0f: - nbank = addr >> 19; - if (nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if (nbank < 10) { - nbank = 2 + (((addr - 0x100000) >> 11) & 1); - addr2 = (addr - 0x100000) >> 12; - } else { - nbank = 4 + ((addr - 0x500000) >> 21); - addr2 = (addr - 0x500000) >> 11; - } - break; - - case 0x08: - nbank = addr >> 19; - if (nbank < 4) { - nbank = 1; - addr2 = addr >> 11; - } else if (nbank == 4) { - nbank = 0; - addr2 = addr >> 10; - } else { - nbank -= 3; - addr2 = addr >> 10; - } - break; - - case 0x09: - nbank = addr >> 19; - if (nbank < 8) { - nbank = 1 + ((addr >> 11) & 1); - addr2 = addr >> 12; - } else if (nbank == 8) { - nbank = 0; - addr2 = addr >> 10; - } else { - nbank -= 6; - addr2 = addr >> 10; - } - break; - - case 0x0a: - nbank = addr >> 19; - if (nbank < 8) { - nbank = 1 + ((addr >> 11) & 1); - addr2 = addr >> 12; - } else if (nbank < 12) { - nbank = 3; - addr2 = addr >> 11; - } else if (nbank == 12) { - nbank = 0; - addr2 = addr >> 10; - } else { - nbank -= 9; - addr2 = addr >> 10; - } - break; - - case 0x0b: - nbank = addr >> 21; - addr2 = addr >> 11; - break; - - case 0x0c: - case 0x0d: - nbank = addr >> 21; - if ((nbank & (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) { - nbank = (addr >> 11) & 1; - addr2 = addr >> 12; - } else - addr2 = addr >> 11; - break; - - case 0x0e: - case 0x13: - nbank = addr >> 21; - if ((nbank & (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) { - nbank = (addr >> 11) & 3; - addr2 = addr >> 13; - } else - addr2 = addr >> 11; - break; - - case 0x10: - case 0x11: - nbank = addr >> 19; - if (nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if (nbank < 10) { - nbank = 2 + (((addr - 0x100000) >> 11) & 1); - addr2 = (addr - 0x100000) >> 12; - } else if (nbank < 18) { - nbank = 4 + (((addr - 0x500000) >> 11) & 1); - addr2 = (addr - 0x500000) >> 12; - } else { - nbank = 6 + ((addr - 0x900000) >> 21); - addr2 = (addr - 0x900000) >> 11; - } - break; - - case 0x12: - nbank = addr >> 19; - if (nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else if (nbank < 10) { - nbank = 2 + (((addr - 0x100000) >> 11) & 1); - addr2 = (addr - 0x100000) >> 12; - } else { - nbank = 4 + (((addr - 0x500000) >> 11) & 3); - addr2 = (addr - 0x500000) >> 13; - } - break; - - case 0x14: - case 0x15: - nbank = addr >> 21; - if ((nbank & 7) < 4) { - nbank = (addr >> 11) & 3; - addr2 = addr >> 13; - } else if ((nbank & 7) < 6) { - nbank = 4 + (((addr - 0x800000) >> 11) & 1); - addr2 = (addr - 0x800000) >> 12; - } else { - nbank = 6 + (((addr - 0xc00000) >> 11) & 3); - addr2 = (addr - 0xc00000) >> 13; - } - break; - - case 0x16: - nbank = ((addr >> 21) & 4) | ((addr >> 11) & 3); - addr2 = addr >> 13; - break; - - case 0x17: - if (dev->external_is_RAS && (addr & 0x800) == 0) - return 0xffffffff; - nbank = addr >> 19; - if (nbank < 2) { - nbank = (addr >> 10) & 1; - addr2 = addr >> 11; - } else { - nbank = 2 + ((addr - 0x100000) >> 23); - addr2 = (addr - 0x100000) >> 12; - } - break; - - case 0x18: - if (dev->external_is_RAS && (addr & 0x800) == 0) - return 0xffffffff; - nbank = addr >> 21; - if (nbank < 4) { - nbank = 1; - addr2 = addr >> 12; - } else if (nbank == 4) { - nbank = 0; - addr2 = addr >> 11; - } else { - nbank -= 3; - addr2 = addr >> 11; - } - break; - - case 0x19: - if (dev->external_is_RAS && (addr & 0x800) == 0) - return 0xffffffff; - nbank = addr >> 23; - if ((nbank & 3) < 2) { - nbank = (addr >> 12) & 1; - addr2 = addr >> 13; - } else - addr2 = addr >> 12; - break; - - default: - if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 6) { - nbank = addr >> 19; - addr2 = (addr >> 10) & 0x1ff; - } else if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 0x17) { - nbank = addr >> 21; - addr2 = (addr >> 11) & 0x3ff; - } else { - nbank = addr >> 23; - addr2 = (addr >> 12) & 0x7ff; - } - break; - } - - nbank &= (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; - - if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) > 0x16 && nbank == 3) - return 0xffffffff; - - if (dev->external_is_RAS && (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) { - if (nbank == 3) - nbank = 7; - else - return 0xffffffff; - } else if (!dev->external_is_RAS && dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x80) { - switch(nbank) { - case 7: - nbank = 3; - break; - - /* Note - In the following cases, the chipset accesses multiple memory banks - at the same time, so it's impossible to predict which memory bank - is actually accessed. */ - case 5: - case 1: - nbank = 1; - break; - - case 3: - nbank = 2; - break; - - default: - nbank = 0; - break; - } - } - - switch(mem_size & ~511) { - case 1024: - case 1536: - addr &= 0x3ff; - if (nbank < 2) - addr |= (nbank << 10) | ((addr2 & 0x1ff) << 11); - else - addr |= ((addr2 & 0x1ff) << 10) | (nbank << 19); - break; - - case 2048: - if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 5) { - addr &= 0x3ff; - if (nbank < 4) - addr |= (nbank << 10) | ((addr2 & 0x1ff) << 12); - else - addr |= ((addr2 & 0x1ff) << 10) | (nbank << 19); - } else { - addr &= 0x7ff; - addr |= ((addr2 & 0x3ff) << 11) | (nbank << 21); - } - break; - - case 2560: - if (nbank == 0) - addr = (addr & 0x3ff) | ((addr2 & 0x1ff) << 10); - else { - addr &= 0x7ff; - addr2 &= 0x3ff; - addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); - } - break; - - case 3072: - if (nbank < 2) - addr = (addr & 0x3ff) | (nbank << 10) | ((addr2 & 0x1ff) << 11); - else - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 11) | ((nbank - 2) << 21)); - break; - - case 4096: - case 6144: - addr &= 0x7ff; - if (nbank < 2) - addr |= (nbank << 11) | ((addr2 & 0x3ff) << 12); - else - addr |= ((addr2 & 0x3ff) << 11) | (nbank << 21); - break; - - case 4608: - if (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) >= 8 && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) <= 0x0a) || ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 0x18)) { - if (nbank == 0) - addr = (addr & 0x3ff) | ((addr2 & 0x1ff) << 10); - else if (nbank < 3) - addr = 0x80000 + ((addr & 0x7ff) | ((nbank - 1) << 11) | ((addr2 & 0x3ff) << 12)); - else - addr = 0x480000 + ((addr & 0x3ff) | ((addr2 & 0x1ff) << 10) | ((nbank - 3) << 19)); - } else if (nbank == 0) - addr = (addr & 0x3ff) | ((addr2 & 0x1ff) << 10); - else { - addr &= 0x7ff; - addr2 &= 0x3ff; - addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); - } - break; - - case 5120: - case 7168: - if (nbank < 2) - addr = (addr & 0x3ff) | (nbank << 10) | ((addr2 & 0x1ff) << 11); - else if (nbank < 4) - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 12) | ((nbank & 1) << 11)); - else - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 11) | ((nbank - 2) << 21)); - break; - - case 6656: - if (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) >= 8 && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) <= 0x0a) || ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 0x18)) { - if (nbank == 0) - addr = (addr & 0x3ff) | ((addr2 & 0x1ff) << 10); - else if (nbank < 3) - addr = 0x80000 + ((addr & 0x7ff) | ((nbank - 1) << 11) | ((addr2 & 0x3ff) << 12)); - else if (nbank == 3) - addr = 0x480000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 11)); - else - addr = 0x680000 + ((addr & 0x3ff) | ((addr2 & 0x1ff) << 10) | ((nbank - 4) << 19)); - } else if (nbank == 0) - addr = (addr & 0x3ff) | ((addr2 & 0x1ff) << 10); - else if (nbank == 1) { - addr &= 0x7ff; - addr2 &= 0x3ff; - addr = addr + 0x80000 + (addr2 << 11); - } else { - addr &= 0x7ff; - addr2 &= 0x3ff; - addr = addr + 0x280000 + ((addr2 << 12) | ((nbank & 1) << 11) | (((nbank - 2) & 6) << 21)); - } - break; - - case 8192: - addr &= 0x7ff; - if (nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3ff) << 13); - else - addr |= ((addr2 & 0x3ff) << 11) | (nbank << 21); - break; - - case 9216: - if (nbank < 2) - addr = (addr & 0x3ff) | (nbank << 10) | ((addr2 & 0x1ff) << 11); - else if (dev->external_is_RAS) { - if (nbank < 6) - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 12) | ((nbank & 1) << 11)); - else - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 11) | ((nbank - 2) << 21)); - } else - addr = 0x100000 + ((addr & 0xfff) | ((addr2 & 0x7ff) << 12) | ((nbank - 2) << 23)); - break; - - case 10240: - if (dev->external_is_RAS) { - addr &= 0x7ff; - if (nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3ff) << 13); - else - addr |= ((addr2 & 0x3ff) << 11) | (nbank << 21); - } else if (nbank == 0) - addr = (addr & 0x7ff) | ((addr2 & 0x3ff) << 11); - else { - addr &= 0xfff; - addr2 &= 0x7ff; - addr = addr + 0x200000 + ((addr2 << 12) | ((nbank - 1) << 23)); - } - break; - - case 11264: - if (nbank < 2) - addr = (addr & 0x3ff) | (nbank << 10) | ((addr2 & 0x1ff) << 11); - else if (nbank < 6) - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 12) | ((nbank & 1) << 11)); - else - addr = 0x100000 + ((addr & 0x7ff) | ((addr2 & 0x3ff) << 11) | ((nbank - 2) << 21)); - break; - - case 12288: - if (dev->external_is_RAS) { - addr &= 0x7ff; - if (nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3ff) << 13); - else if (nbank < 6) - addr |= ((nbank & 1) << 11) | ((addr2 & 0x3ff) << 12) | ((nbank & 4) << 21); - else - addr |= ((addr2 & 0x3ff) << 11) | (nbank << 21); - } else { - if (nbank < 2) - addr = (addr & 0x7ff) | (nbank << 11) | ((addr2 & 0x3ff) << 12); - else - addr = 0x400000 + ((addr & 0xfff) | ((addr2 & 0x7ff) << 12) | ((nbank - 2) << 23)); - } - break; - - case 13312: - if (nbank < 2) - addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); - else if (nbank < 4) - addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); - else - addr = 0x500000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 13) | ((nbank & 3) << 11)); - break; - - case 14336: - addr &= 0x7ff; - if (nbank < 4) - addr |= (nbank << 11) | ((addr2 & 0x3ff) << 13); - else if (nbank < 6) - addr |= ((nbank & 1) << 11) | ((addr2 & 0x3ff) << 12) | ((nbank & 4) << 21); - else - addr |= ((addr2 & 0x3ff) << 11) | (nbank << 21); - break; - - case 16384: - if (dev->external_is_RAS) { - addr &= 0x7ff; - addr2 &= 0x3ff; - addr |= ((nbank & 3) << 11) | (addr2 << 13) | ((nbank & 4) << 21); - } else { - addr &= 0xfff; - addr2 &= 0x7ff; - if (nbank < 2) - addr |= (addr2 << 13) | (nbank << 12); - else - addr |= (addr2 << 12) | (nbank << 23); - } - break; - - default: - if (mem_size < 2048 || ((mem_size & 1536) == 512) || (mem_size == 2048 && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 6)) { - addr &= 0x3ff; - addr2 &= 0x1ff; - addr |= (addr2 << 10) | (nbank << 19); - } else if (mem_size < 8192 || (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 0x17) { - addr &= 0x7ff; - addr2 &= 0x3ff; - addr |= (addr2 << 11) | (nbank << 21); - } else { - addr &= 0xfff; - addr2 &= 0x7ff; - addr |= (addr2 << 12) | (nbank << 23); - } - break; - } - } - - return addr; -} - - -static void -set_global_EMS_state(scat_t *dev, int state) -{ - uint32_t base_addr, virt_addr; - int i, conf; - - for (i = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 24; i < 32; i++) { - base_addr = (i + 16) << 14; - - if (i >= 24) - base_addr += 0x30000; - if (state && (dev->page[i].regs_2x9 & 0x80)) { - virt_addr = get_addr(dev, base_addr, &dev->page[i]); - if (i < 24) - mem_mapping_disable(&dev->efff_mapping[i]); - else - mem_mapping_disable(&dev->efff_mapping[i + 12]); - mem_mapping_enable(&dev->ems_mapping[i]); - - if (virt_addr < ((uint32_t)mem_size << 10)) - mem_mapping_set_exec(&dev->ems_mapping[i], ram + virt_addr); - else - mem_mapping_set_exec(&dev->ems_mapping[i], NULL); - } else { - mem_mapping_set_exec(&dev->ems_mapping[i], ram + base_addr); - mem_mapping_disable(&dev->ems_mapping[i]); - - conf = (dev->regs[SCAT_VERSION] & 0xf0) ? (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) - : (dev->regs[SCAT_DRAM_CONFIGURATION] & 0xf) | ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2); - if (i < 24) { - if (conf > 1 || (conf == 1 && i < 16)) - mem_mapping_enable(&dev->efff_mapping[i]); - else - mem_mapping_disable(&dev->efff_mapping[i]); - } else if (conf > 3 || ((dev->regs[SCAT_VERSION] & 0xf0) != 0 && conf == 2)) - mem_mapping_enable(&dev->efff_mapping[i + 12]); - else - mem_mapping_disable(&dev->efff_mapping[i + 12]); - } - } - - flushmmucache(); -} - - -static void -memmap_state_update(scat_t *dev) -{ - uint32_t addr; - int i; - - for (i = (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0 : 16); i < 44; i++) { - addr = get_addr(dev, 0x40000 + (i << 14), NULL); - mem_mapping_set_exec(&dev->efff_mapping[i], - addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - } - - addr = get_addr(dev, 0, NULL); - mem_mapping_set_exec(&dev->low_mapping[0], - addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - - addr = get_addr(dev, 0xf0000, NULL); - mem_mapping_set_exec(&dev->low_mapping[1], - addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - - for (i = 2; i < 32; i++) { - addr = get_addr(dev, i << 19, NULL); - mem_mapping_set_exec(&dev->low_mapping[i], - addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - } - - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) { - for (i = 0; i < max_map[(dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | ((dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)]; i++) - mem_mapping_enable(&dev->low_mapping[i]); - - for (; i < 32; i++) - mem_mapping_disable(&dev->low_mapping[i]); - - for (i = 24; i < 36; i++) { - if (((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) | (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40)) < 4) - mem_mapping_disable(&dev->efff_mapping[i]); - else - mem_mapping_enable(&dev->efff_mapping[i]); - } - } else { - for (i = 0; i < max_map_sx[dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f]; i++) - mem_mapping_enable(&dev->low_mapping[i]); - - for (; i < 32; i++) - mem_mapping_disable(&dev->low_mapping[i]); - - for(i = 24; i < 36; i++) { - if ((dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) < 2 || (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3) - mem_mapping_disable(&dev->efff_mapping[i]); - else - mem_mapping_enable(&dev->efff_mapping[i]); - } - } - - if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && - (dev->regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((dev->regs[SCAT_VERSION] & 0xf0) != 0)) { - if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && - (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) == 3) || - (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) == 3)) { - mem_mapping_disable(&dev->low_mapping[2]); - - for (i = 0; i < 6; i++) { - addr = get_addr(dev, 0x100000 + (i << 16), NULL); - mem_mapping_set_exec(&dev->remap_mapping[i], - addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL); - mem_mapping_enable(&dev->remap_mapping[i]); - } - } else { - for (i = 0; i < 6; i++) - mem_mapping_disable(&dev->remap_mapping[i]); - - if ((((dev->regs[SCAT_VERSION] & 0xf0) == 0) && - (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x0f) > 4) || (((dev->regs[SCAT_VERSION] & 0xf0) != 0) && (dev->regs[SCAT_DRAM_CONFIGURATION] & 0x1f) > 3)) - mem_mapping_enable(&dev->low_mapping[2]); - } - } else { - for (i = 0; i < 6; i++) - mem_mapping_disable(&dev->remap_mapping[i]); - - mem_mapping_enable(&dev->low_mapping[2]); - } - - set_global_EMS_state(dev, dev->regs[SCAT_EMS_CONTROL] & 0x80); -} - - -static void -scat_write(uint16_t port, uint8_t val, priv_t priv) -{ - scat_t *dev = (scat_t *)priv; - uint8_t reg_valid = 0, - shadow_update = 0, - map_update = 0, - indx; - uint32_t base_addr, virt_addr; - - switch (port) { - case 0x22: - dev->indx = val; - break; - - case 0x23: - switch (dev->indx) { - case SCAT_DMA_WAIT_STATE_CONTROL: - case SCAT_CLOCK_CONTROL: - case SCAT_PERIPHERAL_CONTROL: - reg_valid = 1; - break; - - case SCAT_EMS_CONTROL: - if (val & 0x40) { - if (val & 1) { - io_sethandler(0x0218, 3, scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - io_removehandler(0x0208, 3, scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - } else { - io_sethandler(0x0208, 3, scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - io_removehandler(0x0218, 3, scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - } - } else { - io_removehandler(0x0208, 0x0003, scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - io_removehandler(0x0218, 0x0003, scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - } - set_global_EMS_state(dev, val & 0x80); - reg_valid = 1; - break; - - case SCAT_POWER_MANAGEMENT: - /* TODO - Only use AUX parity disable bit for this version. - Other bits should be implemented later. */ - val &= (dev->regs[SCAT_VERSION] & 0xf0) == 0 ? 0x40 : 0x60; - reg_valid = 1; - break; - - case SCAT_DRAM_CONFIGURATION: - map_update = 1; - - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) { - config.cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; - cpu_update_waitstates(); - } - - reg_valid = 1; - break; - - case SCAT_EXTENDED_BOUNDARY: - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) { - if (dev->regs[SCAT_VERSION] < 4) { - val &= 0xbf; - set_xms_bound(dev, val & 0x0f); - } else { - val = (val & 0x7f) | 0x80; - set_xms_bound(dev, val & 0x4f); - } - } else - set_xms_bound(dev, val & 0x1f); - - mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if ((val ^ dev->regs[SCAT_EXTENDED_BOUNDARY]) & 0xc0) - map_update = 1; - reg_valid = 1; - 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: - reg_valid = 1; - shadow_update = 1; - break; - - case SCATSX_LAPTOP_FEATURES: - if ((dev->regs[SCAT_VERSION] & 0xf0) != 0) { - val = (val & ~8) | (dev->regs[SCATSX_LAPTOP_FEATURES] & 8); - reg_valid = 1; - } - break; - - case SCATSX_FAST_VIDEO_CONTROL: - case SCATSX_FAST_VIDEORAM_ENABLE: - case SCATSX_HIGH_PERFORMANCE_REFRESH: - case SCATSX_CAS_TIMING_FOR_DMA: - if ((dev->regs[SCAT_VERSION] & 0xf0) != 0) - reg_valid = 1; - break; - - default: - break; - } - - if (reg_valid) - dev->regs[dev->indx] = val; - - if (shadow_update) - shadow_state_update(dev); - - if (map_update) - memmap_state_update(dev); - break; - - case 0x92: - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~dev->port_92 & val) & 1) { - cpu_reset(0); - cpu_set_edx(); - } - dev->port_92 = val; - break; - - case 0x208: - case 0x218: - if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) - indx = dev->reg_2xA & 0x1f; - else - indx = ((dev->reg_2xA & 0x40) >> 4) + (dev->reg_2xA & 0x3) + 24; - dev->page[indx].regs_2x8 = val; - base_addr = (indx + 16) << 14; - if (indx >= 24) - base_addr += 0x30000; - - if ((dev->regs[SCAT_EMS_CONTROL] & 0x80) && (dev->page[indx].regs_2x9 & 0x80)) { - virt_addr = get_addr(dev, base_addr, &dev->page[indx]); - if (virt_addr < ((uint32_t)mem_size << 10)) - mem_mapping_set_exec(&dev->ems_mapping[indx], ram + virt_addr); - else - mem_mapping_set_exec(&dev->ems_mapping[indx], NULL); - flushmmucache(); - } - } - break; - - case 0x209: - case 0x219: - if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) - indx = dev->reg_2xA & 0x1f; - else - indx = ((dev->reg_2xA & 0x40) >> 4) + (dev->reg_2xA & 0x3) + 24; - dev->page[indx].regs_2x9 = val; - base_addr = (indx + 16) << 14; - if (indx >= 24) - base_addr += 0x30000; - - if (dev->regs[SCAT_EMS_CONTROL] & 0x80) { - if (val & 0x80) { - virt_addr = get_addr(dev, base_addr, &dev->page[indx]); - if (indx < 24) - mem_mapping_disable(&dev->efff_mapping[indx]); - else - mem_mapping_disable(&dev->efff_mapping[indx + 12]); - if (virt_addr < ((uint32_t)mem_size << 10)) - mem_mapping_set_exec(&dev->ems_mapping[indx], ram + virt_addr); - else - mem_mapping_set_exec(&dev->ems_mapping[indx], NULL); - mem_mapping_enable(&dev->ems_mapping[indx]); - } else { - mem_mapping_set_exec(&dev->ems_mapping[indx], ram + base_addr); - mem_mapping_disable(&dev->ems_mapping[indx]); - if (indx < 24) - mem_mapping_enable(&dev->efff_mapping[indx]); - else - mem_mapping_enable(&dev->efff_mapping[indx + 12]); - } - - flushmmucache(); - } - - if (dev->reg_2xA & 0x80) - dev->reg_2xA = (dev->reg_2xA & 0xe0) | ((dev->reg_2xA + 1) & (((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? 0x1f : 3)); - } - break; - - case 0x20a: - case 0x21a: - if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) - dev->reg_2xA = ((dev->regs[SCAT_VERSION] & 0xf0) == 0) ? val : val & 0xc3; - break; - } -} - - -static uint8_t -scat_read(uint16_t port, priv_t priv) -{ - scat_t *dev = (scat_t *)priv; - uint8_t ret = 0xff, indx; - - switch (port) { - case 0x23: - switch (dev->indx) { - case SCAT_MISCELLANEOUS_STATUS: - ret = (dev->regs[dev->indx] & 0x3f) | (~nmi_mask & 0x80) | ((mem_a20_key & 2) << 5); - break; - - case SCAT_DRAM_CONFIGURATION: - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) - ret = (dev->regs[dev->indx] & 0x8f) | (config.cpu_waitstates == 1 ? 0 : 0x10); - else - ret = dev->regs[dev->indx]; - break; - - case SCAT_EXTENDED_BOUNDARY: - ret = dev->regs[dev->indx]; - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) { - if ((dev->regs[SCAT_VERSION] & 0x0f) >= 4) - ret |= 0x80; - else - ret &= 0xaf; - } - break; - - default: - ret = dev->regs[dev->indx]; - break; - } - break; - - case 0x92: - ret = dev->port_92; - break; - - case 0x208: - case 0x218: - if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) - indx = dev->reg_2xA & 0x1f; - else - indx = ((dev->reg_2xA & 0x40) >> 4) + (dev->reg_2xA & 0x3) + 24; - ret = dev->page[indx].regs_2x8; - } - break; - - case 0x209: - case 0x219: - if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { - if ((dev->regs[SCAT_VERSION] & 0xf0) == 0) - indx = dev->reg_2xA & 0x1f; - else - indx = ((dev->reg_2xA & 0x40) >> 4) + (dev->reg_2xA & 0x3) + 24; - ret = dev->page[indx].regs_2x9; - } - break; - - case 0x20a: - case 0x21a: - if ((dev->regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) - ret = dev->reg_2xA; - break; - } - - return ret; -} - - -static uint8_t -mem_read_scatb(uint32_t addr, priv_t priv) -{ - mem_mapping_t *map = (mem_mapping_t *)priv; - scat_t *dev = (scat_t *)map->dev; - ems_page_t *page = (ems_page_t *)map->p2; - uint8_t val = 0xff; - - addr = get_addr(dev, addr, page); - if (addr < ((uint32_t)mem_size << 10)) - val = ram[addr]; - - return val; -} - - -static uint16_t -mem_read_scatw(uint32_t addr, priv_t priv) -{ - mem_mapping_t *map = (mem_mapping_t *)priv; - scat_t *dev = (scat_t *)map->dev; - ems_page_t *page = (ems_page_t *)map->p2; - uint16_t val = 0xffff; - - addr = get_addr(dev, addr, page); - if (addr < ((uint32_t)mem_size << 10)) - val = *(uint16_t *)&ram[addr]; - - return val; -} - - -static uint32_t -mem_read_scatl(uint32_t addr, priv_t priv) -{ - mem_mapping_t *map = (mem_mapping_t *)priv; - scat_t *dev = (scat_t *)map->dev; - ems_page_t *page = (ems_page_t *)map->p2; - uint32_t val = 0xffffffff; - - addr = get_addr(dev, addr, page); - if (addr < ((uint32_t)mem_size << 10)) - val = *(uint32_t *)&ram[addr]; - - return val; -} - - -static void -mem_write_scatb(uint32_t addr, uint8_t val, priv_t priv) -{ - mem_mapping_t *map = (mem_mapping_t *)priv; - scat_t *dev = (scat_t *)map->dev; - ems_page_t *page = (ems_page_t *)map->p2; - uint32_t oldaddr = addr, chkaddr; - - addr = get_addr(dev, addr, page); - chkaddr = page ? addr : oldaddr; - if (chkaddr >= 0xc0000 && chkaddr < 0x100000) { - if (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15))) return; - } - - if (addr < ((uint32_t)mem_size << 10)) - ram[addr] = val; -} - - -static void -mem_write_scatw(uint32_t addr, uint16_t val, priv_t priv) -{ - mem_mapping_t *map = (mem_mapping_t *)priv; - scat_t *dev = (scat_t *)map->dev; - ems_page_t *page = (ems_page_t *)map->p2; - uint32_t oldaddr = addr, chkaddr; - - addr = get_addr(dev, addr, page); - chkaddr = page ? addr : oldaddr; - if (chkaddr >= 0xc0000 && chkaddr < 0x100000) { - if (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15))) return; - } - - if (addr < ((uint32_t)mem_size << 10)) - *(uint16_t *)&ram[addr] = val; -} - - -static void -mem_write_scatl(uint32_t addr, uint32_t val, priv_t priv) -{ - mem_mapping_t *map = (mem_mapping_t *)priv; - scat_t *dev = (scat_t *)map->dev; - ems_page_t *page = (ems_page_t *)map->p2; - uint32_t oldaddr = addr, chkaddr; - - addr = get_addr(dev, addr, page); - chkaddr = page ? addr : oldaddr; - if (chkaddr >= 0xc0000 && chkaddr < 0x100000) { - if (dev->regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xc0000) >> 15))) return; - } - if (addr < ((uint32_t)mem_size << 10)) - *(uint32_t *)&ram[addr] = val; -} - - -static void -scat_close(priv_t priv) -{ - scat_t *dev = (scat_t *)priv; - - free(dev); -} - - -static priv_t -scat_init(const device_t *info, UNUSED(void *parent)) -{ - scat_t *dev; - uint32_t k; - int i, sx; - - dev = (scat_t *)mem_alloc(sizeof(scat_t)); - memset(dev, 0x00, sizeof(scat_t)); - dev->type = info->local; - - sx = (dev->type == 32) ? 1 : 0; - - for (i = 0; i < sizeof(dev->regs); i++) - dev->regs[i] = 0xff; - - if (sx) { - dev->regs[SCAT_VERSION] = 0x13; - dev->regs[SCAT_CLOCK_CONTROL] = 6; - dev->regs[SCAT_PERIPHERAL_CONTROL] = 0; - dev->regs[SCAT_DRAM_CONFIGURATION] = 1; - dev->regs[SCATSX_LAPTOP_FEATURES] = 0; - dev->regs[SCATSX_FAST_VIDEO_CONTROL] = 0; - dev->regs[SCATSX_FAST_VIDEORAM_ENABLE] = 0; - dev->regs[SCATSX_HIGH_PERFORMANCE_REFRESH] = 8; - dev->regs[SCATSX_CAS_TIMING_FOR_DMA] = 3; - } else { - switch(dev->type) { - case 4: - dev->regs[SCAT_VERSION] = 4; - break; - - default: - dev->regs[SCAT_VERSION] = 1; - break; - } - dev->regs[SCAT_CLOCK_CONTROL] = 2; - dev->regs[SCAT_PERIPHERAL_CONTROL] = 0x80; - dev->regs[SCAT_DRAM_CONFIGURATION] = config.cpu_waitstates == 1 ? 2 : 0x12; - } - dev->regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; - dev->regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; - dev->regs[SCAT_ROM_ENABLE] = 0xc0; - dev->regs[SCAT_RAM_WRITE_PROTECT] = 0; - dev->regs[SCAT_POWER_MANAGEMENT] = 0; - dev->regs[SCAT_SHADOW_RAM_ENABLE_1] = 0; - dev->regs[SCAT_SHADOW_RAM_ENABLE_2] = 0; - dev->regs[SCAT_SHADOW_RAM_ENABLE_3] = 0; - dev->regs[SCAT_EXTENDED_BOUNDARY] = 0; - dev->regs[SCAT_EMS_CONTROL] = 0; - dev->port_92 = 0; - - /* Disable all system mappings, we will override them. */ - mem_mapping_disable(&ram_low_mapping); - if (! sx) - mem_mapping_disable(&ram_mid_mapping); - mem_mapping_disable(&ram_high_mapping); - for (i = 0; i < 4; i++) - mem_mapping_disable(&bios_mapping[i]); - - k = (sx) ? 0x80000 : 0x40000; - mem_mapping_add(&dev->low_mapping[0], 0, k, - mem_read_scatb, mem_read_scatw, mem_read_scatl, - mem_write_scatb, mem_write_scatw, mem_write_scatl, - ram, MEM_MAPPING_INTERNAL, &dev->low_mapping[0]); - mem_mapping_set_dev(&dev->low_mapping[0], dev); - - mem_mapping_add(&dev->low_mapping[1], 0xf0000, 0x10000, - mem_read_scatb,mem_read_scatw,mem_read_scatl, - mem_write_scatb,mem_write_scatw,mem_write_scatl, - ram + 0xf0000, MEM_MAPPING_INTERNAL, &dev->low_mapping[1]); - mem_mapping_set_dev(&dev->low_mapping[1], dev); - - for (i = 2; i < 32; i++) { - mem_mapping_add(&dev->low_mapping[i], (i << 19), 0x80000, - mem_read_scatb,mem_read_scatw,mem_read_scatl, - mem_write_scatb,mem_write_scatw,mem_write_scatl, - ram + (i<<19), MEM_MAPPING_INTERNAL, &dev->low_mapping[i]); - mem_mapping_set_dev(&dev->low_mapping[i], dev); - } - - if (sx) { - i = 16; - k = 0x40000; - } else { - i = 0; - k = (dev->regs[SCAT_VERSION] < 4) ? 0x40000 : 0x60000; - } - mem_mapping_set_addr(&dev->low_mapping[31], 0xf80000, k); - - for (; i < 44; i++) { - mem_mapping_add(&dev->efff_mapping[i], 0x40000 + (i << 14), 0x4000, - mem_read_scatb,mem_read_scatw,mem_read_scatl, - mem_write_scatb,mem_write_scatw,mem_write_scatl, - mem_size > (256 + (i << 4)) ? ram + 0x40000 + (i << 14) : NULL, - MEM_MAPPING_INTERNAL, &dev->efff_mapping[i]); - mem_mapping_set_dev(&dev->efff_mapping[i], dev); - - if (sx) - mem_mapping_enable(&dev->efff_mapping[i]); - } - - for (i = 0; i < 8; i++) { - mem_mapping_add(&dev->romcs_mapping[i], 0xc0000 + (i << 14), 0x4000, - rom_bios_read,rom_bios_readw,rom_bios_readl, - mem_write_null,mem_write_nullw,mem_write_nulll, - bios + ((i << 14) & biosmask), - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); - mem_mapping_disable(&dev->romcs_mapping[i]); - } - - if (sx) { - for (i = 24; i < 32; i++) { - dev->page[i].regs_2x8 = 0xff; - dev->page[i].regs_2x9 = 0x03; - mem_mapping_add(&dev->ems_mapping[i], (i + 28) << 14, 0x04000, - mem_read_scatb,mem_read_scatw,mem_read_scatl, - mem_write_scatb,mem_write_scatw,mem_write_scatl, - ram + ((i + 28) << 14), 0, &dev->ems_mapping[i]); - mem_mapping_set_dev(&dev->ems_mapping[i], dev); - mem_mapping_set_p2(&dev->ems_mapping[i], &dev->page[i]); - mem_mapping_disable(&dev->ems_mapping[i]); - } - - for (i = 0; i < 16; i++) { - mem_mapping_add(&dev->high_mapping[i], (i << 14) + 0xfc0000, 0x04000, - rom_bios_read,rom_bios_readw,rom_bios_readl, - mem_write_null,mem_write_nullw,mem_write_nulll, - bios + ((i << 14) & biosmask), 0, NULL); - mem_mapping_enable(&dev->high_mapping[i]); - } - } else { - for (i = 0; i < 32; i++) { - dev->page[i].regs_2x8 = 0xff; - dev->page[i].regs_2x9 = 0x03; - mem_mapping_add(&dev->ems_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, - mem_read_scatb,mem_read_scatw,mem_read_scatl, - mem_write_scatb,mem_write_scatw,mem_write_scatl, - ram + ((i + (i >= 24 ? 28 : 16)) << 14), - 0, &dev->ems_mapping[i]); - mem_mapping_set_dev(&dev->ems_mapping[i], dev); - mem_mapping_set_p2(&dev->ems_mapping[i], &dev->page[i]); - } - - for (i = (dev->regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) { - mem_mapping_add(&dev->high_mapping[i], (i << 14) + 0xfc0000, 0x04000, - rom_bios_read,rom_bios_readw,rom_bios_readl, - mem_write_null,mem_write_nullw,mem_write_nulll, - bios + ((i << 14) & biosmask), 0, NULL); - mem_mapping_enable(&dev->high_mapping[i]); - } - } - - for (i = 0; i < 6; i++) { - mem_mapping_add(&dev->remap_mapping[i], 0x100000 + (i << 16), 0x10000, - mem_read_scatb,mem_read_scatw,mem_read_scatl, - mem_write_scatb,mem_write_scatw,mem_write_scatl, - mem_size >= 1024 ? ram + get_addr(dev, 0x100000 + (i << 16), NULL) : NULL, - MEM_MAPPING_INTERNAL, &dev->remap_mapping[i]); - mem_mapping_set_dev(&dev->remap_mapping[i], dev); - } - - if (sx) { - dev->external_is_RAS = scatsx_external_is_RAS[mem_size >> 9]; - } else { - dev->external_is_RAS = (dev->regs[SCAT_VERSION] > 3) || (((mem_size & ~2047) >> 11) + ((mem_size & 1536) >> 9) + ((mem_size & 511) >> 7)) > 4; - } - - set_xms_bound(dev, 0); - memmap_state_update(dev); - shadow_state_update(dev); - - io_sethandler(0x0022, 2, - scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - io_sethandler(0x0092, 1, - scat_read,NULL,NULL, scat_write,NULL,NULL, dev); - - return((priv_t)dev); -} - - -const device_t scat_device = { - "C&T SCAT (v1)", - 0, - 0, - NULL, - scat_init, scat_close, NULL, - NULL, NULL, NULL, NULL, - NULL -}; - -const device_t scat_4_device = { - "C&T SCAT (v4)", - 0, - 4, - NULL, - scat_init, scat_close, NULL, - NULL, NULL, NULL, NULL, - NULL -}; - -const device_t scat_sx_device = { - "C&T SCATsx", - 0, - 32, - NULL, - scat_init, scat_close, NULL, - NULL, NULL, NULL, NULL, - NULL -}; diff --git a/src/chipset/wd76c10 - Cópia.c b/src/chipset/wd76c10 - Cópia.c deleted file mode 100644 index 7a834e910..000000000 --- a/src/chipset/wd76c10 - Cópia.c +++ /dev/null @@ -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, - * Miran Grca, - * Fred N. van Kempen, - * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - */ -#include -#include -#include -#include -#include -#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 -}; diff --git a/src/dma.c b/src/dma.c index 59b4cef71..7322f471e 100644 --- a/src/dma.c +++ b/src/dma.c @@ -8,7 +8,7 @@ * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.c 1.0.6 2019/09/21 + * Version: @(#)dma.c 1.0.7 2019/09/28 * * Authors: Sarah Walker, * Miran Grca, @@ -51,6 +51,10 @@ static uint8_t dma_stat_rq; static uint8_t dma_stat_rq_pc; static uint8_t dma_command, dma16_command; +static uint8_t dma_req_is_soft; +static uint8_t dma_buffer[65536]; +static uint16_t dma16_buffer[65536]; + static struct { int xfr_command, xfr_channel; @@ -87,6 +91,31 @@ dma_set_drq(int channel, int set) } +static void +dma_block_transfer(int channel) +{ + int i, bit16; + + bit16 = (channel >= 4); + + dma_req_is_soft = 1; + for (i = 0; i <= dma[channel].cb; i++) { + if ((dma[channel].mode & 0x8c) == 0x84) { + if (bit16) + dma_channel_write(channel, dma16_buffer[i]); + else + dma_channel_write(channel, dma_buffer[i]); + } else if ((dma[channel].mode & 0x8c) == 0x88) { + if (bit16) + dma16_buffer[i] = dma_channel_read(channel); + else + dma_buffer[i] = dma_channel_read(channel); + } + } + dma_req_is_soft = 0; +} + + static uint8_t dma_read(uint16_t addr, void *priv) { @@ -168,17 +197,19 @@ dma_write(uint16_t addr, uint8_t val, void *priv) case 9: /*Request register */ channel = (val & 3); - if (val & 4) + if (val & 4) { dma_stat_rq_pc |= (1 << channel); - else + dma_block_transfer(channel); + } else dma_stat_rq_pc &= ~(1 << channel); break; case 0xa: /*Mask*/ + channel = (val & 3); if (val & 4) - dma_m |= (1 << (val & 3)); - else - dma_m &= ~(1 << (val & 3)); + dma_m |= (1 << channel); + else + dma_m &= ~(1 << channel); return; case 0xb: /*Mode*/ @@ -462,17 +493,19 @@ dma16_write(uint16_t addr, uint8_t val, void *priv) case 9: /*Request register */ channel = (val & 3) + 4; - if (val & 4) + if (val & 4) { dma_stat_rq_pc |= (1 << channel); - else + dma_block_transfer(channel); + } else dma_stat_rq_pc &= ~(1 << channel); break; case 0xa: /*Mask*/ + channel = (val & 3); if (val & 4) - dma_m |= (0x10 << (val & 3)); - else - dma_m &= ~(0x10 << (val & 3)); + dma_m |= (0x10 << channel); + else + dma_m &= ~(0x10 << channel); return; case 0xb: /*Mode*/ @@ -582,8 +615,8 @@ dma_reset(void) dma_wp = dma16_wp = 0; dma_m = 0; - for (c = 0; c < 16; c++) - dmaregs[c] = 0; + for (c = 0; c < 16; c++) + dmaregs[c] = dma16regs[c] = 0; for (c = 0; c < 8; c++) { dma[c].mode = 0; dma[c].ac = 0; @@ -596,6 +629,10 @@ dma_reset(void) dma_stat = 0x00; dma_stat_rq = 0x00; dma_stat_rq_pc = 0x00; + dma_req_is_soft = 0; + + memset(dma_buffer, 0x00, sizeof(dma_buffer)); + memset(dma16_buffer, 0x00, sizeof(dma16_buffer)); } @@ -699,7 +736,7 @@ dma_channel_read(int channel) return(DMA_NODATA); } - if (dma_m & (1 << channel)) + if ((dma_m & (1 << channel)) && !dma_req_is_soft) return(DMA_NODATA); if ((dma_c->mode & 0xC) != 8) return(DMA_NODATA); @@ -772,7 +809,7 @@ dma_channel_write(int channel, uint16_t val) return(DMA_NODATA); } - if (dma_m & (1 << channel)) + if ((dma_m & (1 << channel)) && !dma_req_is_soft) return(DMA_NODATA); if ((dma_c->mode & 0xC) != 4) return(DMA_NODATA); diff --git a/src/intel_flash.c b/src/intel_flash.c index 764b97fa9..3bb43d2f2 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -295,16 +295,16 @@ intel_flash_add_mappings(flash_t *dev) mem_mapping_add(&(dev->mapping[i]), base, 0x10000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array + fbase, MEM_MAPPING_EXTERNAL, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev); } mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - 0x40000, 0x10000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array + fbase, MEM_MAPPING_EXTERNAL, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev); mem_mapping_add(&(dev->mapping_h[i + 4]), (base | 0xfff00000), 0x10000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array + fbase, MEM_MAPPING_EXTERNAL, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev); } } diff --git a/src/mem.c b/src/mem.c index 05dfaa7ba..0ef1b81e3 100644 --- a/src/mem.c +++ b/src/mem.c @@ -844,6 +844,23 @@ writememql(uint32_t seg, uint32_t addr, uint64_t val) } +int +mem_mapping_is_romcs(uint32_t addr, int write) +{ + mem_mapping_t *map; + + if (write) + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + else + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map) + return !!(map->flags & MEM_MAPPING_ROMCS); + else + return 0; +} + + #if 0 uint8_t mem_readb_phys(uint32_t addr) @@ -1420,19 +1437,19 @@ mem_add_bios(void) mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, - &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); } else { mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); } if (AT) { mem_mapping_add(&bios_high_mapping, biosaddr | (cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); } } diff --git a/src/mem.h b/src/mem.h index 8ec7f7458..40225811b 100644 --- a/src/mem.h +++ b/src/mem.h @@ -42,6 +42,7 @@ #define MEM_MAPPING_INTERNAL 2 /* on internal bus (RAM) */ #define MEM_MAPPING_ROM 4 /* Executing from ROM may involve * additional wait states. */ +#define MEM_MAPPING_ROMCS 8 /* respond to ROMCS* */ #define MEM_MAP_TO_SHADOW_RAM_MASK 1 #define MEM_MAP_TO_RAM_ADDR_MASK 2 @@ -271,6 +272,7 @@ extern void mem_mapping_set_addr(mem_mapping_t *, extern void mem_mapping_set_exec(mem_mapping_t *, uint8_t *exec); extern void mem_mapping_disable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *); +extern int mem_mapping_is_romcs(uint32_t addr, int write); extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); diff --git a/src/mem_new.c b/src/mem_new.c index 941c2f676..797e2f599 100644 --- a/src/mem_new.c +++ b/src/mem_new.c @@ -821,6 +821,23 @@ writememql(uint32_t addr, uint64_t val) } +int +mem_mapping_is_romcs(uint32_t addr, int write) +{ + mem_mapping_t *map; + + if (write) + map = write_mapping[addr >> MEM_GRANULARITY_BITS]; + else + map = read_mapping[addr >> MEM_GRANULARITY_BITS]; + + if (map) + return !!(map->flags & MEM_MAPPING_ROMCS); + else + return 0; +} + + uint8_t mem_readb_phys(uint32_t addr) { @@ -1415,12 +1432,12 @@ mem_add_bios(void) mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, - &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); } else { mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, - rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); } if (AT) { @@ -1428,7 +1445,7 @@ mem_add_bios(void) mem_read_bios,mem_read_biosw,mem_read_biosl, mem_write_null,mem_write_nullw,mem_write_nulll, rom, - MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); } } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 932f205b8..049572cd5 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -8,13 +8,13 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.c 1.0.26 2018/10/18 + * Version: @(#)vid_ati_mach64.c 1.0.27 2019/09/28 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include @@ -3310,10 +3310,10 @@ static void *mach64_common_init(const device_t *info) if (info->flags & DEVICE_PCI) mem_mapping_disable(&mach64->bios_rom.mapping); - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); - mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &mach64->svga); + mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); + mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); + mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); mem_mapping_disable(&mach64->mmio_mapping); mach64_io_set(mach64); diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index bc45fcd12..2fcbd189c 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -10,13 +10,13 @@ * * Known bugs: Accelerator doesn't work in planar modes * - * Version: @(#)vid_et4000w32.c 1.0.21 2018/10/18 + * Version: @(#)vid_et4000w32.c 1.0.22 2019/09/28 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include @@ -1266,8 +1266,8 @@ void *et4000w32p_init(const device_t *info) if (info->flags & DEVICE_PCI) mem_mapping_disable(&et4000->bios_rom.mapping); - mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &et4000->svga); - mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, 0, et4000); + mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &et4000->svga); + mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, et4000); et4000w32p_io_set(et4000); diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index f7866dfee..e14e68346 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -8,7 +8,7 @@ * * Video 7 VGA 1024i emulation. * - * Version: @(#)vid_ht216.c 1.0.0 2019/04/05 + * Version: @(#)vid_ht216.c 1.0.1 2019/09/28 * * Authors: Sarah Walker, * Miran Grca, @@ -1058,7 +1058,7 @@ void mem_mapping_set_handler(&ht216->svga.mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, ht216_writel); mem_mapping_set_p(&ht216->svga.mapping, ht216); - mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, 0, &ht216->svga); + mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &ht216->svga); svga->bpp = 8; svga->miscout = 1; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 4f0a17837..637709c1a 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -44,7 +44,7 @@ * * This is expected to be done shortly. * - * Version: @(#)vid_pgc.c 1.0.2 2019/03/03 + * Version: @(#)vid_pgc.c 1.0.3 2019/09/28 * * Authors: Fred N. van Kempen, * John Elliott, @@ -2633,7 +2633,6 @@ pgc_init(pgc_t *dev, int maxw, int maxh, int visw, int vish, /* Make it a 16k mapping at C4000 (will be C4000-C7FFF), because of the emulator's granularity - the original mapping will conflict with hard disk controller BIOS'es. */ - // mem_mapping_add(&dev->mapping, 0xc6000, 2048, mem_mapping_add(&dev->mapping, 0xc4000, 16384, pgc_read,NULL,NULL, pgc_write,NULL,NULL, NULL, MEM_MAPPING_EXTERNAL, dev); diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 3734ce454..be9305330 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -47,13 +47,13 @@ * access size or host data has any affect, but the Windows 3.1 * driver always reads bytes and write words of 0xffff. * - * Version: @(#)vid_tgui9440.c 1.0.9 2018/10/04 + * Version: @(#)vid_tgui9440.c 1.0.10 2019/09/28 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include @@ -1679,8 +1679,8 @@ static void *tgui_init(const device_t *info) if (tgui->type == TGUI_9400CXI) tgui->svga.ramdac = device_add(&tkd8001_ramdac_device); - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); - mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, &tgui->svga); + mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); mem_mapping_disable(&tgui->accel_mapping); io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);