diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index adf59197c..0685e0346 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -38,7 +38,6 @@ enum INTEL_430LX, INTEL_430NX, INTEL_430FX, - INTEL_430FX_PB640, INTEL_430HX, INTEL_430VX, INTEL_430TX, @@ -46,14 +45,15 @@ enum INTEL_440LX, INTEL_440EX, INTEL_440BX, - INTEL_440GX, + INTEL_440GX, INTEL_440ZX }; typedef struct { uint8_t pm2_cntrl, max_func, - smram_locked; + smram_locked, max_drb, + drb_default; uint8_t regs[2][256], regs_locked[2][256]; int type; } i4x0_t; @@ -81,55 +81,28 @@ i4x0_map(uint32_t addr, uint32_t size, int state) static void -i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int ram) +i4x0_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) { - int state = ram ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY); - - mem_set_mem_state_common(smm, addr, size, state); - flushmmucache(); + mem_set_mem_state_smram(smm, addr, size, is_smram); } static void i4x0_smram_handler_phase0(i4x0_t *dev) { - uint32_t i, n; + uint32_t tom = (mem_size << 10); /* Disable any active mappings. */ - if (dev->type >= INTEL_430FX) { - if (dev->type >= INTEL_440LX) { - /* Disable high extended SMRAM. */ - /* TODO: This area should point to A0000-FFFFF. */ - for (i = 0x100a0000; i < 0x100fffff; i += MEM_GRANULARITY_SIZE) { - /* This is to make sure that if the remaining area is smaller than - or equal to MEM_GRANULARITY_SIZE, we do not change the state of - too much memory. */ - n = ((mem_size << 10) - i); - /* Cap to MEM_GRANULARITY_SIZE if i is either at or beyond the end - of RAM or the remaining area is bigger than MEM_GRANULARITY_SIZE. */ - if ((i >= (mem_size << 10)) || (n > MEM_GRANULARITY_SIZE)) - n = MEM_GRANULARITY_SIZE; - i4x0_smram_map(0, i, n, (i < (mem_size << 10))); - i4x0_smram_map(1, i, n, (i < (mem_size << 10))); - if (n < MEM_GRANULARITY_SIZE) { - i4x0_smram_map(0, i + n, MEM_GRANULARITY_SIZE - n, 0); - i4x0_smram_map(1, i + n, MEM_GRANULARITY_SIZE - n, 0); - } - } + if (smram[0].host_base != 0x00000000) { + i4x0_smram_map(0, smram[0].host_base, ram_smram_mapping[0].size, 0); + i4x0_smram_map(1, smram[0].host_base, ram_smram_mapping[0].size, 0); + } - /* Disable TSEG. */ - i4x0_smram_map(1, ((mem_size << 10) - (1 << 20)), (1 << 20), 1); - } + if ((dev->type >= INTEL_440BX) && (smram[1].host_base != 0x00000000)) { + i4x0_smram_map(1, smram[1].host_base, ram_smram_mapping[1].size, 0); - /* Disable low extended SMRAM. */ - i4x0_smram_map(0, 0xa0000, 0x20000, 0); - i4x0_smram_map(1, 0xa0000, 0x20000, 0); - } else { - /* Disable low extended SMRAM. */ - i4x0_smram_map(0, 0xa0000, 0x20000, 0); - i4x0_smram_map(0, (mem_size << 10) - 0x10000, 0x10000, 1); - i4x0_smram_map(1, 0xa0000, 0x20000, 0); - i4x0_smram_map(1, (mem_size << 10) - 0x10000, 0x10000, 1); + tom -= (1 << 20); + mem_set_mem_state_smm(tom, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } } @@ -138,20 +111,33 @@ static void i4x0_smram_handler_phase1(i4x0_t *dev) { uint8_t *regs = (uint8_t *) dev->regs[0]; + uint32_t tom = (mem_size << 10); uint32_t s, base[2] = { 0x000a0000, 0x00020000 }; uint32_t size[2] = { 0, 0 }; if (dev->type >= INTEL_430FX) { /* Set temporary bases and sizes. */ + smram[0].ram_base = 0x000a0000; if ((dev->type >= INTEL_440BX) && (regs[0x73] & 0x80)) { base[0] = 0x100a0000; size[0] = 0x00060000; + smram[0].host_base = 0x100a0000; } else { - base[0] = 0x000a0000; - size[0] = 0x00020000; + if (((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) && ((regs[0x72] & 0x07) == 0x04)) { + base[0] = 0x000c0000; + size[0] = 0x00010000; + smram[0].host_base = smram[0].ram_base = 0x000c0000; + } else { + base[0] = 0x000a0000; + size[0] = 0x00020000; + smram[0].host_base = 0x000a0000; + } } + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size[0]); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + /* If D_OPEN = 1 and D_LCK = 0, extended SMRAM is visible outside SMM. */ i4x0_smram_map(0, base[0], size[0], ((regs[0x72] & 0x70) == 0x40)); @@ -162,10 +148,25 @@ i4x0_smram_handler_phase1(i4x0_t *dev) if (dev->type >= INTEL_440BX) { if ((regs[0x72] & 0x08) && (regs[0x73] & 0x01)) { size[1] = (1 << (17 + ((regs[0x73] >> 1) & 0x03))); - base[1] = (mem_size << 10) - size[1]; + tom -= size[1]; + base[1] = tom; } else base[1] = size[1] = 0x00000000; - i4x0_smram_map(1, base[1], size[1], 1); + + if (size[1] != 0x00000000) { + mem_set_mem_state_smm(base[1], size[1], MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + smram[1].host_base = base[1] + (1 << 28); + smram[1].ram_base = base[1]; + + mem_mapping_set_addr(&ram_smram_mapping[1], smram[1].host_base, size[1]); + if (smram[1].ram_base < (1 << 30)) + mem_mapping_set_exec(&ram_smram_mapping[1], ram + smram[1].ram_base); + else + mem_mapping_set_exec(&ram_smram_mapping[1], ram2 + smram[1].ram_base - (1 << 30)); + + i4x0_smram_map(1, smram[1].host_base, size[1], 1); + } } else base[1] = size[1] = 0x00000000; } else { @@ -204,6 +205,8 @@ i4x0_smram_handler_phase1(i4x0_t *dev) /* If we are not closed, point to RAM. */ } } + + flushmmucache(); } @@ -259,7 +262,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) default: regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42); break; - case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: + case INTEL_430FX: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: case INTEL_440FX: case INTEL_440LX: case INTEL_440EX: regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02); break; @@ -280,7 +283,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) default: regs[0x07] &= ~(val & 0x70); break; - case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430VX: case INTEL_430TX: + case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: case INTEL_440LX: case INTEL_440EX: regs[0x07] &= ~(val & 0x30); break; @@ -304,7 +307,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) break; case 0x0f: switch (dev->type) { - case INTEL_430FX: case INTEL_430FX_PB640: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: + case INTEL_430FX: case INTEL_430HX: case INTEL_430VX: case INTEL_430TX: regs[0x0f] = (val & 0x40); break; } @@ -365,7 +368,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: regs[0x50] = (val & 0xe7); break; - case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430FX: regs[0x50] = (val & 0xef); break; case INTEL_430HX: @@ -420,8 +423,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case 0x52: /* Cache Control Register */ switch (dev->type) { case INTEL_420TX: case INTEL_420ZX: - case INTEL_430LX: - case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430LX: case INTEL_430FX: case INTEL_430VX: case INTEL_430TX: default: regs[0x52] = (val & 0xfb); @@ -516,8 +518,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430NX: case INTEL_440EX: regs[0x57] = val; break; - case INTEL_430FX: case INTEL_430FX_PB640: - case INTEL_430HX: case INTEL_430VX: + case INTEL_430FX: case INTEL_430HX: + case INTEL_430VX: regs[0x57] = val & 0xcf; break; case INTEL_430TX: @@ -547,8 +549,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_440BX: case INTEL_440ZX: regs[0x58] = val & 0x03; break; - case INTEL_430FX: case INTEL_430FX_PB640: - case INTEL_440FX: + case INTEL_430FX: case INTEL_440FX: regs[0x58] = val & 0x7f; break; case INTEL_430HX: case INTEL_430VX: @@ -629,8 +630,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) default: regs[addr] = val; break; - case INTEL_430FX: case INTEL_430FX_PB640: - case INTEL_430VX: + case INTEL_430FX: case INTEL_430VX: regs[addr] = val & 0x3f; break; case INTEL_430TX: @@ -690,7 +690,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430VX: case INTEL_430TX: regs[0x68] = val; break; - case INTEL_430FX: case INTEL_430FX_PB640: + case INTEL_430FX: regs[0x68] = val & 0x1f; break; case INTEL_440FX: case INTEL_440LX: @@ -802,7 +802,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) if (dev->smram_locked) regs[0x72] = (regs[0x72] & 0xdf) | (val & 0x20); else { - regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78); + if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) + regs[0x72] = (regs[0x72] & 0x80) | (val & 0x7f); + else + regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78); dev->smram_locked = (val & 0x10); if (dev->smram_locked) regs[0x72] &= 0xbf; @@ -814,7 +817,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x72] = (regs[0x72] & 0xc0) | (val & 0x3f); dev->smram_locked = (val & 0x08); if (dev->smram_locked) - regs[0x72] &= 0xef; + regs[0x72] &= 0xdf; } } i4x0_smram_handler_phase1(dev); @@ -1225,10 +1228,16 @@ i4x0_reset(void *priv) for (i = 0; i < 6; i++) i4x0_write(0, 0x5a + i, 0x00, priv); - if (dev->type >= INTEL_430FX) + for (i = 0; i <= dev->max_drb; i++) + i4x0_write(0, 0x60 + i, dev->drb_default, priv); + + if (dev->type >= INTEL_430FX) { + dev->regs[0][0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x02, priv); - else + } else { + dev->regs[0][0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x00, priv); + } if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) { for (i = 0; i <= dev->max_func; i++) @@ -1291,6 +1300,8 @@ static void regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; + dev->max_drb = 5; + dev->drb_default = 0x02; break; case INTEL_430LX: regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ @@ -1307,6 +1318,8 @@ static void regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02; + dev->max_drb = 5; + dev->drb_default = 0x02; break; case INTEL_430NX: regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */ @@ -1325,12 +1338,12 @@ static void regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; + dev->max_drb = 7; + dev->drb_default = 0x02; break; - case INTEL_430FX_PB640: - regs[0x08] = 0x02; - /* FALLTHROUGH */ case INTEL_430FX: regs[0x02] = 0x2d; regs[0x03] = 0x12; /* SB82437FX-66 */ + regs[0x08] = (info->local >> 8) & 0xff; regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */ if (cpu_busspeed <= 50000000) regs[0x57] |= 0x01; @@ -1340,6 +1353,8 @@ static void regs[0x57] |= 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02; regs[0x72] = 0x02; + dev->max_drb = 4; + dev->drb_default = 0x02; break; case INTEL_430HX: regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */ @@ -1352,6 +1367,8 @@ static void regs[0x57] |= 0x03; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_default = 0x02; break; case INTEL_430VX: regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */ @@ -1371,6 +1388,8 @@ static void regs[0x72] = 0x02; regs[0x74] = 0x0e; regs[0x78] = 0x23; + dev->max_drb = 4; + dev->drb_default = 0x02; break; case INTEL_430TX: regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */ @@ -1386,6 +1405,8 @@ static void regs[0x67] |= 0x80; regs[0x70] = 0x20; regs[0x72] = 0x02; + dev->max_drb = 5; + dev->drb_default = 0x02; break; case INTEL_440FX: regs[0x02] = 0x37; regs[0x03] = 0x12; /* 82441FX */ @@ -1400,6 +1421,8 @@ static void regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02; regs[0x71] = 0x10; regs[0x72] = 0x02; + dev->max_drb = 7; + dev->drb_default = 0x02; break; case INTEL_440LX: dev->max_func = 1; @@ -1422,6 +1445,8 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; case INTEL_440EX: dev->max_func = 1; @@ -1444,6 +1469,8 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; case INTEL_440BX: case INTEL_440ZX: regs[0x7a] = (info->local >> 8) & 0xff; @@ -1470,6 +1497,8 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; case INTEL_440GX: regs[0x7a] = (info->local >> 8) & 0xff; @@ -1493,6 +1522,8 @@ static void regs[0xa4] = 0x03; regs[0xa5] = 0x02; regs[0xa7] = 0x1f; + dev->max_drb = 7; + dev->drb_default = 0x01; break; } @@ -1632,7 +1663,7 @@ const device_t i430fx_pb640_device = { "Intel SB82437FX-66 (PB640)", DEVICE_PCI, - INTEL_430FX_PB640, + 0x0200 | INTEL_430FX, i4x0_init, i4x0_close, i4x0_reset, diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 6122f2761..6955c025c 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -64,20 +64,12 @@ apollo_map(uint32_t addr, uint32_t size, int state) static void -apollo_smram_map(int smm, uint32_t addr, uint32_t size, int ram) +apollo_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) { - int state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, size); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); - if (ram == 0) - state = (MEM_READ_EXTANY | MEM_WRITE_EXTANY); - else if (ram == 1) - state = (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else if (ram == 2) - state = (MEM_READ_EXTERNAL_EX | MEM_WRITE_EXTANY); - else if (ram == 3) - state = (MEM_READ_DISABLED | MEM_WRITE_DISABLED); - - mem_set_mem_state_common(smm, addr, size, state); + mem_set_mem_state_smram_ex(smm, addr, size, is_smram & 0x03); flushmmucache(); } @@ -272,6 +264,12 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) if ((dev->pci_conf[0][0x63] ^ val) & 0xc0) apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6); dev->pci_conf[0][0x63] = val; + mem_set_mem_state_smram_ex(0, 0x00030000, 0x00020000, 0x00); + mem_set_mem_state_smram_ex(1, 0x00030000, 0x00020000, 0x00); + mem_set_mem_state_smram_ex(0, 0x000a0000, 0x00020000, 0x00); + mem_set_mem_state_smram_ex(1, 0x000a0000, 0x00020000, 0x00); + smram[0].host_base = 0x000a0000; + smram[0].ram_base = 0x000a0000; if (dev->id == 0x0691) switch (val & 0x03) { case 0x00: default: @@ -310,9 +308,9 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) /* Reserved */ apollo_smram_map(1, 0x000a0000, 0x00020000, 3); if (dev->id == 0x0597) { - /* TODO: SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx - (this needs a 3xxxx-4xxxx mapping set to EXTERNAL). */ - apollo_smram_map(1, 0x00030000, 0x00020000, 3); + /* SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx. */ + smram[0].host_base = 0x00030000; + apollo_smram_map(1, 0x00030000, 0x00020000, 1); } apollo_smram_map(0, 0x000a0000, 0x00020000, 3); break; diff --git a/src/config.c b/src/config.c index 419bcc324..2425769c0 100644 --- a/src/config.c +++ b/src/config.c @@ -536,8 +536,8 @@ load_machine(void) mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); #endif - if (mem_size > 1048576) - mem_size = 1048576; + if (mem_size > 2097152) + mem_size = 2097152; cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); diff --git a/src/include/86box/intel_420ex.h b/src/include/86box/intel_420ex.h new file mode 100644 index 000000000..a052c277d --- /dev/null +++ b/src/include/86box/intel_420ex.h @@ -0,0 +1,15 @@ +/* + * 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. + * + * Emulation of Intel 420EX PCI chip. + * + * + * + * Author: Miran Grca, + * Copyright 2020 Miran Grca. + */ + +extern const device_t i420ex_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 18ada3e7b..8efced08b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -241,6 +241,7 @@ extern int machine_at_alfredo_init(const machine_t *); #if defined(DEV_BRANCH) && defined(NO_SIO) extern int machine_at_486sp3g_init(const machine_t *); #endif +extern int machine_at_486ap4_init(const machine_t *); /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 3abcdb44c..80b736acb 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -27,31 +27,45 @@ #define MEM_MAPPING_ROM 4 /* Executing from ROM may involve * additional wait states. */ #define MEM_MAPPING_ROMCS 8 /* respond to ROMCS* */ +#define MEM_MAPPING_SMRAM 16 /* on internal bus (RAM) but SMRAM */ #define MEM_MAP_TO_SHADOW_RAM_MASK 1 #define MEM_MAP_TO_RAM_ADDR_MASK 2 -#define MEM_READ_ANY 0x00 -#define MEM_READ_INTERNAL 0x10 -#define MEM_READ_EXTERNAL 0x20 -#define MEM_READ_DISABLED 0x30 -#define MEM_READ_NORMAL 0x40 /* SMM only - means use the non-SMM state */ -#define MEM_READ_EXTERNAL_EX 0x50 /* External but with internal exec - needed by the VIA Apollo Pro */ -#define MEM_READ_ROMCS 0x60 /* EXTERNAL type + ROMC flag */ -#define MEM_READ_EXTANY 0x70 /* Any EXTERNAL type */ -#define MEM_READ_MASK 0xf0 +/* _mem_state layout: + Bits 0 - 7: Normal write + Bits 8 -15: Normal read + Bits 16 -23: SMM write + Bits 24 -31: SMM read +*/ -#define MEM_WRITE_ANY 0x00 -#define MEM_WRITE_INTERNAL 0x01 -#define MEM_WRITE_EXTERNAL 0x02 -#define MEM_WRITE_DISABLED 0x03 -#define MEM_WRITE_NORMAL 0x04 /* SMM only - means use the non-SMM state */ -#define MEM_WRITE_EXTERNAL_EX 0x05 -#define MEM_WRITE_ROMCS 0x06 /* EXTERNAL type + ROMC flag */ -#define MEM_WRITE_EXTANY 0x07 /* Any EXTERNAL type */ -#define MEM_WRITE_MASK 0x0f +#define MEM_READ_ANY 0x0000 +#define MEM_READ_INTERNAL 0x0100 +#define MEM_READ_EXTERNAL 0x0200 +#define MEM_READ_DISABLED 0x0300 +#define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */ +#define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */ +#define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */ +#define MEM_READ_EXTANY 0x0700 /* Any EXTERNAL type */ +#define MEM_READ_SMRAM 0x1000 +#define MEM_READ_SMRAM_EX 0x2000 +#define MEM_READ_DISABLED_EX 0x4000 +#define MEM_READ_MASK 0xff00 -#define MEM_STATE_SMM_SHIFT 8 +#define MEM_WRITE_ANY 0x0000 +#define MEM_WRITE_INTERNAL 0x0001 +#define MEM_WRITE_EXTERNAL 0x0002 +#define MEM_WRITE_DISABLED 0x0003 +#define MEM_WRITE_NORMAL 0x0004 /* SMM only - means use the non-SMM state */ +#define MEM_WRITE_EXTERNAL_EX 0x0005 +#define MEM_WRITE_ROMCS 0x0006 /* EXTERNAL type + ROMC flag */ +#define MEM_WRITE_EXTANY 0x0007 /* Any EXTERNAL type */ +#define MEM_WRITE_SMRAM 0x0010 +#define MEM_WRITE_SMRAM_EX 0x0020 +#define MEM_WRITE_DISABLED_EX 0x0040 +#define MEM_WRITE_MASK 0x00ff + +#define MEM_STATE_SMM_SHIFT 16 /* #define's for memory granularity, currently 16k, but may change in the future - 4k works, less does not because of @@ -162,7 +176,14 @@ typedef struct _page_ { #endif -extern uint8_t *ram; +typedef struct +{ + uint32_t host_base, + ram_base; +} smram_t; + + +extern uint8_t *ram, *ram2; extern uint32_t rammask; extern uint8_t *rom; @@ -185,6 +206,8 @@ extern mem_mapping_t base_mapping, #endif ram_remapped_mapping, ram_high_mapping, + ram_2gb_mapping, + ram_smram_mapping[2], bios_mapping, bios_high_mapping; @@ -193,7 +216,8 @@ extern uint32_t mem_logical_addr; extern page_t *pages, **page_lookup; -extern uint32_t get_phys_virt,get_phys_phys; +extern uint32_t get_phys_virt, get_phys_phys; +extern smram_t smram[2]; extern int shadowbios, shadowbios_write; @@ -278,9 +302,14 @@ extern void mem_mapping_recalc(uint64_t base, uint64_t size); extern void mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state); +extern void mem_set_mem_state_smram(int smm, uint32_t base, uint32_t size, int is_smram); +extern void mem_set_mem_state_smram_ex(int smm, uint32_t base, uint32_t size, int is_smram); + extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); extern void mem_set_mem_state_smm(uint32_t base, uint32_t size, int state); +extern void mem_set_mem_state_both(uint32_t base, uint32_t size, int state); + extern uint8_t mem_readb_phys(uint32_t addr); extern uint16_t mem_readw_phys(uint32_t addr); extern uint32_t mem_readl_phys(uint32_t addr); @@ -297,6 +326,13 @@ extern void mem_write_ram(uint32_t addr, uint8_t val, void *priv); extern void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); extern void mem_write_raml(uint32_t addr, uint32_t val, void *priv); +extern uint8_t mem_read_smram(uint32_t addr, void *priv); +extern uint16_t mem_read_smramw(uint32_t addr, void *priv); +extern uint32_t mem_read_smraml(uint32_t addr, void *priv); +extern void mem_write_smram(uint32_t addr, uint8_t val, void *priv); +extern void mem_write_smramw(uint32_t addr, uint16_t val, void *priv); +extern void mem_write_smraml(uint32_t addr, uint32_t val, void *priv); + extern uint8_t mem_read_bios(uint32_t addr, void *priv); extern uint16_t mem_read_biosw(uint32_t addr, void *priv); extern uint32_t mem_read_biosl(uint32_t addr, void *priv); diff --git a/src/intel_420ex.c b/src/intel_420ex.c new file mode 100644 index 000000000..1a74ad6c8 --- /dev/null +++ b/src/intel_420ex.c @@ -0,0 +1,564 @@ +/* + * 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. + * + * Emulation of Intel 82420EX chipset that acts as both the + * northbridge and the southbridge. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/apm.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/machine.h> +#include <86box/intel_420ex.h> + + +#define MEM_STATE_SHADOW_R 0x01 +#define MEM_STATE_SHADOW_W 0x02 +#define MEM_STATE_SMRAM 0x04 + + +typedef struct +{ + uint8_t id, smram_locked, + regs[256]; + + uint16_t timer_base, + timer_latch; + + double fast_off_period; + + pc_timer_t timer, fast_off_timer; + + apm_t * apm; + port_92_t * port_92; +} i420ex_t; + + +#ifdef ENABLE_I420EX_LOG +int i420ex_do_log = ENABLE_I420EX_LOG; + + +static void +i420ex_log(const char *fmt, ...) +{ + va_list ap; + + if (i420ex_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define i420ex_log(fmt, ...) +#endif + + +static void +i420ex_map(uint32_t addr, uint32_t size, int state) +{ + switch (state & 3) { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + + +static void +i420ex_smram_map(i420ex_t *dev, int smm, uint32_t addr, uint32_t size, int is_smram) +{ + mem_set_mem_state_smram(smm, addr, size, is_smram); + flushmmucache(); +} + + +static void +i420ex_smram_handler_phase0(i420ex_t *dev) +{ + /* Disable low extended SMRAM. */ + i420ex_smram_map(dev, 0, 0xa0000, 0x60000, 0); + i420ex_smram_map(dev, 1, 0xa0000, 0x60000, 0); +} + + +static void +i420ex_smram_handler_phase1(i420ex_t *dev) +{ + uint8_t *regs = (uint8_t *) dev->regs; + + uint32_t base = 0x000a0000; + uint32_t size = 0x00010000; + + switch (regs[0x70] & 0x07) { + case 0: case 1: + default: + base = size = 0x00000000; + break; + case 2: + base = 0x000a0000; + smram[0].host_base = 0x000a0000; + smram[0].ram_base = 0x000a0000; + break; + case 3: + base = 0x000b0000; + smram[0].host_base = 0x000b0000; + smram[0].ram_base = 0x000b0000; + break; + case 4: + base = 0x000c0000; + smram[0].host_base = 0x000c0000; + smram[0].ram_base = 0x000a0000; + break; + case 5: + base = 0x000d0000; + smram[0].host_base = 0x000d0000; + smram[0].ram_base = 0x000a0000; + break; + case 6: + base = 0x000e0000; + smram[0].host_base = 0x000e0000; + smram[0].ram_base = 0x000a0000; + break; + case 7: + base = 0x000f0000; + smram[0].host_base = 0x000f0000; + smram[0].ram_base = 0x000a0000; + break; + } + + if (base != 0x00000000) { + mem_mapping_set_addr(&ram_smram_mapping[0], smram[0].host_base, 0x00010000); + mem_mapping_set_exec(&ram_smram_mapping[0], ram + smram[0].ram_base); + + /* If OSS = 1 and LSS = 0, extended SMRAM is visible outside SMM. */ + i420ex_smram_map(dev, 0, base, size, (regs[0x70] & 0x70) == 0x40); + + /* If the register is set accordingly, disable the mapping also in SMM. */ + i420ex_smram_map(dev, 1, base, size, !(regs[0x70] & 0x20)); + } +} + + +static void +i420ex_write(int func, int addr, uint8_t val, void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + + if (func > 0) + return; + + if (((addr >= 0x0f) && (addr < 0x4c)) && (addr != 0x40)) + return; + + /* The IB (original) variant of the I420EX has no PCI IRQ steering. */ + if ((addr >= 0x60) && (addr <= 0x63) && (dev->id < 0x03)) + return; + + switch (addr) { + case 0x05: + dev->regs[addr] = (val & 0x01); + break; + + case 0x07: + dev->regs[addr] &= ~(val & 0xf0); + break; + + case 0x40: + dev->regs[addr] = (val & 0x7f); + break; + case 0x44: + dev->regs[addr] = (val & 0x07); + break; + case 0x48: + dev->regs[addr] = (val & 0x3f); +#ifdef USE_420EX_IDE + ide_pri_disable(); + switch (val & 0x03) { + case 0x01: + ide_set_base(0, 0x01f0); + ide_set_side(0, 0x03f6); + ide_pri_enable(); + break; + case 0x02: + ide_set_base(0, 0x0170); + ide_set_side(0, 0x0376); + ide_pri_enable(); + break; + } +#endif + break; + case 0x49: case 0x53: + dev->regs[addr] = (val & 0x1f); + break; + case 0x4c: case 0x51: + case 0x57: + case 0x60: case 0x61: case 0x62: case 0x63: + case 0x64: + case 0x68: case 0x69: + dev->regs[addr] = val; + if (addr == 0x4c) { + dma_alias_remove(); + if (!(val & 0x80)) + dma_alias_set(); + } + break; + case 0x4d: + dev->regs[addr] = (dev->regs[addr] & 0xef) | (val & 0x10); + break; + case 0x4e: + dev->regs[addr] = (val & 0xf7); + break; + case 0x50: + dev->regs[addr] = (val & 0x0f); + break; + case 0x52: + dev->regs[addr] = (val & 0x7f); + break; + case 0x56: + dev->regs[addr] = (val & 0x3e); + break; + case 0x59: /* PAM0 */ + if ((dev->regs[0x59] ^ val) & 0xf0) { + i420ex_map(0xf0000, 0x10000, val >> 4); + shadowbios = (val & 0x10); + } + dev->regs[0x59] = val & 0xf0; + break; + case 0x5a: /* PAM1 */ + if ((dev->regs[0x5a] ^ val) & 0x0f) + i420ex_map(0xc0000, 0x04000, val & 0xf); + if ((dev->regs[0x5a] ^ val) & 0xf0) + i420ex_map(0xc4000, 0x04000, val >> 4); + dev->regs[0x5a] = val; + break; + case 0x5b: /*PAM2 */ + if ((dev->regs[0x5b] ^ val) & 0x0f) + i420ex_map(0xc8000, 0x04000, val & 0xf); + if ((dev->regs[0x5b] ^ val) & 0xf0) + i420ex_map(0xcc000, 0x04000, val >> 4); + dev->regs[0x5b] = val; + break; + case 0x5c: /*PAM3 */ + if ((dev->regs[0x5c] ^ val) & 0x0f) + i420ex_map(0xd0000, 0x04000, val & 0xf); + if ((dev->regs[0x5c] ^ val) & 0xf0) + i420ex_map(0xd4000, 0x04000, val >> 4); + dev->regs[0x5c] = val; + break; + case 0x5d: /* PAM4 */ + if ((dev->regs[0x5d] ^ val) & 0x0f) + i420ex_map(0xd8000, 0x04000, val & 0xf); + if ((dev->regs[0x5d] ^ val) & 0xf0) + i420ex_map(0xdc000, 0x04000, val >> 4); + dev->regs[0x5d] = val; + break; + case 0x5e: /* PAM5 */ + if ((dev->regs[0x5e] ^ val) & 0x0f) + i420ex_map(0xe0000, 0x04000, val & 0xf); + if ((dev->regs[0x5e] ^ val) & 0xf0) + i420ex_map(0xe4000, 0x04000, val >> 4); + dev->regs[0x5e] = val; + break; + case 0x5f: /* PAM6 */ + if ((dev->regs[0x5f] ^ val) & 0x0f) + i420ex_map(0xe8000, 0x04000, val & 0xf); + if ((dev->regs[0x5f] ^ val) & 0xf0) + i420ex_map(0xec000, 0x04000, val >> 4); + dev->regs[0x5f] = val; + break; + case 0x66: case 0x67: + i420ex_log("Set IRQ routing: INT %c -> %02X\n", 0x41 + (addr & 0x01), val); + dev->regs[addr] = val & 0x8f; + if (val & 0x80) + pci_set_irq_routing(PCI_INTA + (addr & 0x01), PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA + (addr & 0x01), val & 0xf); + break; + case 0x70: /* SMRAM */ + i420ex_smram_handler_phase0(dev); + if (dev->smram_locked) + dev->regs[0x70] = (dev->regs[0x70] & 0xdf) | (val & 0x20); + else { + dev->regs[0x70] = (dev->regs[0x70] & 0x88) | (val & 0x77); + dev->smram_locked = (val & 0x10); + if (dev->smram_locked) + dev->regs[0x70] &= 0xbf; + } + i420ex_smram_handler_phase1(dev); + break; + case 0xa0: + dev->regs[addr] = val & 0x1f; + apm_set_do_smi(dev->apm, !!(val & 0x01) && !!(dev->regs[0xa2] & 0x80)); + switch ((val & 0x18) >> 3) { + case 0x00: + dev->fast_off_period = PCICLK * 32768.0 * 60000.0; + break; + case 0x01: + default: + dev->fast_off_period = 0.0; + break; + case 0x02: + dev->fast_off_period = PCICLK; + break; + case 0x03: + dev->fast_off_period = PCICLK * 32768.0; + break; + } + cpu_fast_off_count = dev->regs[0xa8] + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + break; + case 0xa2: + dev->regs[addr] = val & 0xff; + apm_set_do_smi(dev->apm, !!(dev->regs[0xa0] & 0x01) && !!(val & 0x80)); + break; + case 0xaa: case 0xac: case 0xae: + if (dev->id == 0x03) + dev->regs[addr] = val & 0xff; + break; + case 0xa4: + dev->regs[addr] = val & 0xfb; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffffff00) | dev->regs[addr]; + break; + case 0xa5: + dev->regs[addr] = val; + cpu_fast_off_flags = (cpu_fast_off_flags & 0xffff00ff) | (dev->regs[addr] << 8); + break; + case 0xa7: + dev->regs[addr] = val & 0xe0; + cpu_fast_off_flags = (cpu_fast_off_flags & 0x00ffffff) | (dev->regs[addr] << 24); + break; + case 0xa8: + dev->regs[addr] = val & 0xff; + cpu_fast_off_val = val; + cpu_fast_off_count = val + 1; + timer_disable(&dev->fast_off_timer); + if (dev->fast_off_period != 0.0) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + break; + } +} + + +static uint8_t +i420ex_read(int func, int addr, void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + uint8_t ret; + + ret = 0xff; + + if (func == 0) + ret = dev->regs[addr]; + + return ret; +} + + +static void +i420ex_reset_hard(void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + + memset(dev->regs, 0, 256); + + dev->regs[0x00] = 0x86; dev->regs[0x01] = 0x80; /*Intel*/ + dev->regs[0x02] = 0x86; dev->regs[0x03] = 0x04; /*82378IB (I420EX)*/ + dev->regs[0x04] = 0x07; + dev->regs[0x07] = 0x02; + dev->regs[0x08] = dev->id; + + dev->regs[0x4c] = 0x4d; + dev->regs[0x4e] = 0x03; + /* Bits 2:1 of register 50h are 00 is 25 MHz, and 01 if 33 MHz, 10 and 11 are reserved. */ + if (cpu_busspeed >= 33333333) + dev->regs[0x50] |= 0x02; + dev->regs[0x51] = 0x80; + dev->regs[0x60] = dev->regs[0x61] = dev->regs[0x62] = dev->regs[0x63] = dev->regs[0x64] = 0x01; + dev->regs[0x66] = 0x80; dev->regs[0x67] = 0x80; + dev->regs[0x69] = 0x02; + dev->regs[0xa0] = 0x08; + dev->regs[0xa8] = 0x0f; + + mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); +} + + +static void +i420ex_apm_out(uint16_t port, uint8_t val, void *p) +{ + i420ex_t *dev = (i420ex_t *) p; + + if (dev->apm->do_smi) + dev->regs[0xaa] |= 0x80; +} + + +static void +i420ex_fast_off_count(void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + + cpu_fast_off_count--; + + if (cpu_fast_off_count == 0) { + smi_line = 1; + dev->regs[0xaa] |= 0x20; + cpu_fast_off_count = dev->regs[0xa8] + 1; + } + + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); +} + + +static void +i420ex_reset(void *p) +{ + i420ex_t *dev = (i420ex_t *) p; + int i; + + for (i = 0; i < 7; i++) + i420ex_write(0, 0x59 + i, 0x00, p); + + for (i = 0; i <= 4; i++) + i420ex_write(0, 0x60 + i, 0x01, p); + + dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */ + dev->smram_locked = 0; + i420ex_write(0, 0x70, 0x00, p); + + mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + i420ex_write(0, 0xa0, 0x08, p); + i420ex_write(0, 0xa2, 0x00, p); + i420ex_write(0, 0xa4, 0x00, p); + i420ex_write(0, 0xa5, 0x00, p); + i420ex_write(0, 0xa6, 0x00, p); + i420ex_write(0, 0xa7, 0x00, p); + i420ex_write(0, 0xa8, 0x0f, p); +} + + +static void +i420ex_close(void *p) +{ + i420ex_t *dev = (i420ex_t *)p; + + free(dev); +} + + +static void +i420ex_speed_changed(void *priv) +{ + i420ex_t *dev = (i420ex_t *) priv; + int te; + + te = timer_is_enabled(&dev->timer); + + timer_disable(&dev->timer); + if (te) + timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC); + + if (dev->id == 0x03) { + te = timer_is_enabled(&dev->fast_off_timer); + + timer_stop(&dev->fast_off_timer); + if (te) + timer_on_auto(&dev->fast_off_timer, dev->fast_off_period); + } +} + + +static void * +i420ex_init(const device_t *info) +{ + i420ex_t *dev = (i420ex_t *) malloc(sizeof(i420ex_t)); + memset(dev, 0, sizeof(i420ex_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev); + + dev->id = info->local; + + timer_add(&dev->fast_off_timer, i420ex_fast_off_count, dev, 0); + + i420ex_reset_hard(dev); + + cpu_fast_off_flags = 0x00000000; + + cpu_fast_off_val = dev->regs[0xa8]; + cpu_fast_off_count = cpu_fast_off_val + 1; + + dev->apm = device_add(&apm_pci_device); + /* APM intercept handler to update 82420EX SMI status on APM SMI. */ + io_sethandler(0x00b2, 0x0001, NULL, NULL, NULL, i420ex_apm_out, NULL, NULL, dev); + + dev->port_92 = device_add(&port_92_pci_device); + + dma_alias_set(); + +#ifdef USE_420EX_IDE + device_add(&ide_pci_device); + ide_pri_disable(); +#else + device_add(&ide_pci_2ch_device); +#endif + + return dev; +} + + +const device_t i420ex_device = +{ + "Intel 82420EX", + DEVICE_PCI, + 0x00, + i420ex_init, + i420ex_close, + i420ex_reset, + NULL, + i420ex_speed_changed, + NULL, + NULL +}; diff --git a/src/intel_sio.c b/src/intel_sio.c index 70ad0ebfc..07146548d 100644 --- a/src/intel_sio.c +++ b/src/intel_sio.c @@ -173,7 +173,7 @@ sio_write(int func, int addr, uint8_t val, void *priv) return; dma_alias_remove(); - if (val & 0x40) + if (!(val & 0x40)) dma_alias_set(); } else dev->regs[addr] = (val & 0x3f); diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 5f44c434b..af4e6797f 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -40,6 +40,7 @@ #include <86box/video.h> #include <86box/intel_flash.h> #include <86box/sst_flash.h> +#include <86box/intel_420ex.h> #include <86box/intel_sio.h> #include <86box/scsi_ncr53c8xx.h> #include <86box/machine.h> @@ -474,10 +475,38 @@ machine_at_486sp3g_init(const machine_t *model) device_add(&sio_device); /* Site says it has a ZB, but the BIOS is designed for an IB. */ device_add(&pc87306_device); /*PC87332*/ device_add(&sst_flash_29ee010_device); - device_add(&ncr53c810_pci_device); device_add(&i420zx_device); return ret; } #endif + + +int +machine_at_486ap4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/486ap4/0205.002", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1 | PCI_NO_IRQ_STEERING); + /* Excluded: 5, 6, 7, 8 */ + pci_register_slot(0x05, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 09 = Slot 1 */ + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0a = Slot 2 */ + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0b = Slot 3 */ + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 0c = Slot 4 */ + device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ + device_add(&fdc_at_device); + + device_add(&i420ex_device); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5c677af47..b1cb3736f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -198,6 +198,7 @@ const machine_t machines[] = { #endif /* 486 machines which utilize the PCI bus */ + { "[486 PCI] ASUS PVI-486AP4", "486ap4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486ap4_init, NULL }, #if defined(DEV_BRANCH) && defined(NO_SIO) { "[486 PCI] ASUS PCI/I-486SP3G", "486sp3g", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 128, 1, 127, machine_at_486sp3g_init, NULL }, #endif @@ -313,8 +314,7 @@ const machine_t machines[] = { /* Slot 2 machines */ /* 440GX */ - /* Till the Heap limit issue is resolved. This board will use 1GB max instead of 2GB */ - { "[Slot 2 GX] Gigabyte GA-6GXU", "6gxu", {{"Intel", cpus_Xeon}, {"", NULL},{"", NULL},{"", NULL},{"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 16, 1024, 16, 511, machine_at_6gxu_init, NULL }, + { "[Slot 2 GX] Gigabyte GA-6GXU", "6gxu", {{"Intel", cpus_Xeon}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 16, 2048, 16, 511, machine_at_6gxu_init, NULL }, /* PGA370 machines */ /* 440LX */ diff --git a/src/mem.c b/src/mem.c index 4fa0d435b..71cf714c3 100644 --- a/src/mem.c +++ b/src/mem.c @@ -64,8 +64,10 @@ mem_mapping_t base_mapping, #endif ram_remapped_mapping, /* 640..1024K mapping */ ram_high_mapping, /* 1024K+ mapping */ + ram_2gb_mapping, /* 1024M+ mapping */ ram_remapped_mapping, ram_split_mapping, + ram_smram_mapping[2], bios_mapping, bios_high_mapping; @@ -73,7 +75,7 @@ page_t *pages, /* RAM page table */ **page_lookup; /* pagetable lookup */ uint32_t pages_sz; /* #pages in table */ -uint8_t *ram; /* the virtual RAM */ +uint8_t *ram, *ram2; /* the virtual RAM */ uint32_t rammask; uint8_t *rom; /* the virtual ROM */ @@ -102,6 +104,8 @@ int cachesize = 256; uint32_t get_phys_virt, get_phys_phys; +smram_t smram[2] = { { 0x000a0000, 0x000a0000 }, { 0x000a0000, 0x000a0000 } }; + int mem_a20_key = 0, mem_a20_alt = 0, mem_a20_state = 0; @@ -122,7 +126,7 @@ int use_phys_exec = 0; static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; -static int _mem_state[MEM_MAPPINGS_NO]; +static uint32_t _mem_state[MEM_MAPPINGS_NO]; #if FIXME #if (MEM_GRANULARITY_BITS >= 12) @@ -272,10 +276,17 @@ mem_flush_write_page(uint32_t addr, uint32_t virt) { page_t *page_target = &pages[addr >> 12]; int c; + uint32_t a; for (c = 0; c < 256; c++) { if (writelookup[c] != (int) 0xffffffff) { - uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; + a = (uintptr_t)(addr & ~0xfff) - (virt & ~0xfff); + uintptr_t target; + + if ((addr & ~0xfff) >= (1 << 30)) + target = (uintptr_t)&ram2[a - (1 << 30)]; + else + target = (uintptr_t)&ram[a]; if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { writelookup2[writelookup[c]] = -1; @@ -562,6 +573,8 @@ mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) void addreadlookup(uint32_t virt, uint32_t phys) { + uint32_t a; + if (virt == 0xffffffff) return; if (readlookup2[virt>>12] != (uintptr_t) -1) return; @@ -569,7 +582,12 @@ addreadlookup(uint32_t virt, uint32_t phys) if (readlookup[readlnext] != (int) 0xffffffff) readlookup2[readlookup[readlnext]] = -1; - readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff); + + if ((phys & ~0xfff) >= (1 << 30)) + readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; + else + readlookup2[virt>>12] = (uintptr_t)&ram[a]; readlookupp[readlnext] = mmu_perm; readlookup[readlnext++] = virt >> 12; @@ -582,6 +600,8 @@ addreadlookup(uint32_t virt, uint32_t phys) void addwritelookup(uint32_t virt, uint32_t phys) { + uint32_t a; + if (virt == 0xffffffff) return; if (page_lookup[virt >> 12]) return; @@ -601,8 +621,14 @@ addwritelookup(uint32_t virt, uint32_t phys) #endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - else - writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + else { + a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff); + + if ((phys & ~0xfff) >= (1 << 30)) + writelookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)]; + else + writelookup2[virt>>12] = (uintptr_t)&ram[a]; + } writelookupp[writelnext] = mmu_perm; writelookup[writelnext++] = virt >> 12; @@ -1566,6 +1592,87 @@ mem_read_raml(uint32_t addr, void *priv) } +uint8_t +mem_read_ram_2gb(uint32_t addr, void *priv) +{ +#ifdef ENABLE_MEM_LOG + if ((addr >= 0xa0000) && (addr <= 0xbffff)) + mem_log("Read B %02X from %08X\n", ram[addr], addr); +#endif + + addreadlookup(mem_logical_addr, addr); + + return ram2[addr - (1 << 30)]; +} + + +uint16_t +mem_read_ram_2gbw(uint32_t addr, void *priv) +{ +#ifdef ENABLE_MEM_LOG + if ((addr >= 0xa0000) && (addr <= 0xbffff)) + mem_log("Read W %04X from %08X\n", *(uint16_t *)&ram[addr], addr); +#endif + + addreadlookup(mem_logical_addr, addr); + + return *(uint16_t *)&ram2[addr - (1 << 30)]; +} + + +uint32_t +mem_read_ram_2gbl(uint32_t addr, void *priv) +{ +#ifdef ENABLE_MEM_LOG + if ((addr >= 0xa0000) && (addr <= 0xbffff)) + mem_log("Read L %08X from %08X\n", *(uint32_t *)&ram[addr], addr); +#endif + + addreadlookup(mem_logical_addr, addr); + + return *(uint32_t *)&ram2[addr - (1 << 30)]; +} + + +uint8_t +mem_read_smram(uint32_t addr, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + if (new_addr >= (1 << 30)) + return mem_read_ram_2gb(new_addr, priv); + else + return mem_read_ram(new_addr, priv); +} + + +uint16_t +mem_read_smramw(uint32_t addr, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + if (new_addr >= (1 << 30)) + return mem_read_ram_2gbw(new_addr, priv); + else + return mem_read_ramw(new_addr, priv); +} + + +uint32_t +mem_read_smraml(uint32_t addr, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + if (new_addr >= (1 << 30)) + return mem_read_ram_2gbl(new_addr, priv); + else + return mem_read_raml(new_addr, priv); +} + + #ifdef USE_NEW_DYNAREC static inline int page_index(page_t *p) @@ -1760,6 +1867,36 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) } +void +mem_write_smram(uint32_t addr, uint8_t val, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + mem_write_ram(new_addr, val, priv); +} + + +void +mem_write_smramw(uint32_t addr, uint16_t val, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + mem_write_ramw(new_addr, val, priv); +} + + +void +mem_write_smraml(uint32_t addr, uint32_t val, void *priv) +{ + smram_t *dev = (smram_t *) priv; + uint32_t new_addr = addr - dev->host_base + dev->ram_base; + + mem_write_raml(new_addr, val, priv); +} + + static uint8_t mem_read_remapped(uint32_t addr, void *priv) { @@ -1924,40 +2061,49 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) static __inline int -mem_mapping_read_allowed(uint32_t flags, int state, int exec) +mem_mapping_read_allowed(uint32_t flags, uint32_t state, int exec) { - int smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t state_masked; if (in_smm && ((smm_state & MEM_READ_MASK) != MEM_READ_NORMAL)) state = smm_state; - switch (state & MEM_READ_MASK) { + state_masked = (state & MEM_READ_MASK); + + if (state_masked & MEM_READ_SMRAM) + return (flags & MEM_MAPPING_SMRAM); + else if ((state_masked & MEM_READ_SMRAM_EX) && exec) + return (flags & MEM_MAPPING_SMRAM); + else if (state_masked & MEM_READ_DISABLED_EX) + return 0; + else switch (state_masked) { case MEM_READ_DISABLED: return 0; case MEM_READ_ANY: - return 1; + return !(flags & MEM_MAPPING_SMRAM); /* On external and 0 mappings without ROMCS. */ case MEM_READ_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); /* On external and 0 mappings with ROMCS. */ case MEM_READ_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); /* On any external mappings. */ case MEM_READ_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); case MEM_READ_EXTERNAL_EX: if (exec) - return !(flags & MEM_MAPPING_EXTERNAL); + return !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); else - return !(flags & MEM_MAPPING_INTERNAL); + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); case MEM_READ_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); + return !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); default: fatal("mem_mapping_read_allowed : bad state %x\n", state); @@ -1968,34 +2114,41 @@ mem_mapping_read_allowed(uint32_t flags, int state, int exec) static __inline int -mem_mapping_write_allowed(uint32_t flags, int state) +mem_mapping_write_allowed(uint32_t flags, uint32_t state) { - int smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t smm_state = state >> MEM_STATE_SMM_SHIFT; + uint32_t state_masked; if (in_smm && ((smm_state & MEM_WRITE_MASK) != MEM_WRITE_NORMAL)) state = smm_state; - switch (state & MEM_WRITE_MASK) { + state_masked = (state & MEM_WRITE_MASK); + + if (state_masked & MEM_WRITE_SMRAM) + return (flags & MEM_MAPPING_SMRAM); + else if (state_masked & MEM_WRITE_DISABLED_EX) + return 0; + else switch (state_masked) { case MEM_WRITE_DISABLED: return 0; case MEM_WRITE_ANY: - return 1; + return !(flags & MEM_MAPPING_SMRAM); /* On external and 0 mappings without ROMCS. */ case MEM_WRITE_EXTERNAL: - return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS); + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); /* On external and 0 mappings with ROMCS. */ case MEM_WRITE_ROMCS: - return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS); + return !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM); /* On any external mappings. */ case MEM_WRITE_EXTANY: - return !(flags & MEM_MAPPING_INTERNAL); + return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM); case MEM_WRITE_INTERNAL: - return !(flags & MEM_MAPPING_EXTERNAL); + return !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); default: fatal("mem_mapping_write_allowed : bad state %x\n", state); @@ -2216,9 +2369,9 @@ mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state) for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { if (smm) - _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0x00ff) | ((state & 0xff) << 8); + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xf0f0ffff) | ((state & 0x0f0f) << MEM_STATE_SMM_SHIFT); else - _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xff00) | (state & 0xff); + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xfffff0f0) | (state & 0x0f0f); #ifdef ENABLE_MEM_LOG if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff)) mem_log("Set mem state for block at %08X to %02X\n", c + base, state); @@ -2229,6 +2382,63 @@ mem_set_mem_state_common(int smm, uint32_t base, uint32_t size, int state) } +void +mem_set_mem_state_smram(int smm, uint32_t base, uint32_t size, int is_smram) +{ + uint32_t c, smstate = 0x0000; + + smstate = is_smram ? (MEM_READ_SMRAM | MEM_WRITE_SMRAM) : 0x0000; + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + if (smm) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0x0f0fffff) | (smstate << MEM_STATE_SMM_SHIFT); + else + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xffff0f0f) | smstate; +#ifdef ENABLE_MEM_LOG + if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff)) + mem_log("Set mem state SMRAM flag for block at %08X to %02X\n", c + base, state); +#endif + } + + mem_mapping_recalc(base, size); +} + + +void +mem_set_mem_state_smram_ex(int smm, uint32_t base, uint32_t size, int is_smram) +{ + uint32_t c, smstate = 0x0000; + + switch (is_smram & 0x03) { + case 0x00: + smstate = 0x0000; + break; + case 0x01: + smstate = (MEM_READ_SMRAM | MEM_WRITE_SMRAM); + break; + case 0x02: + smstate = MEM_READ_SMRAM_EX; + break; + case 0x03: + smstate = (MEM_READ_DISABLED_EX | MEM_WRITE_DISABLED_EX); + break; + } + + for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { + if (smm) + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0x0f0fffff) | (smstate << MEM_STATE_SMM_SHIFT); + else + _mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & 0xffff0f0f) | smstate; +#ifdef ENABLE_MEM_LOG + if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff)) + mem_log("Set mem state SMRAM flag for block at %08X to %02X\n", c + base, state); +#endif + } + + mem_mapping_recalc(base, size); +} + + void mem_set_mem_state(uint32_t base, uint32_t size, int state) { @@ -2243,6 +2453,14 @@ mem_set_mem_state_smm(uint32_t base, uint32_t size, int state) } +void +mem_set_mem_state_both(uint32_t base, uint32_t size, int state) +{ + mem_set_mem_state_common(0, base, size, state); + mem_set_mem_state_common(1, base, size, state); +} + + void mem_add_bios(void) { @@ -2260,16 +2478,16 @@ mem_add_bios(void) mem_write_null,mem_write_nullw,mem_write_nulll, &rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - mem_set_mem_state(0x0e0000, 0x20000, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state_both(0x0e0000, 0x20000, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); } 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|MEM_MAPPING_ROMCS, 0); - mem_set_mem_state(biosaddr, biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state_both(biosaddr, biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); } if (AT) { @@ -2278,8 +2496,8 @@ mem_add_bios(void) mem_write_null,mem_write_nullw,mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); - mem_set_mem_state(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, - MEM_READ_ROMCS | MEM_WRITE_ROMCS); + mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, + MEM_READ_ROMCS | MEM_WRITE_ROMCS); } } @@ -2310,8 +2528,22 @@ mem_reset(void) free(ram); ram = NULL; } - ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ - memset(ram, 0x00, m); + if (ram2 != NULL) { + free(ram2); + ram2 = NULL; + } + if (mem_size > 2097152) + fatal("Attempting to use more than 2 GB of guest RAM\n"); + + if (mem_size > 1048576) { + ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */ + memset(ram, 0x00, 1 << 30); + ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */ + memset(ram2, 0x00, m - (1 << 30)); + } else { + ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */ + memset(ram, 0x00, m); + } /* * Allocate the page table based on how much RAM we have. @@ -2396,7 +2628,13 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); #endif for (c = 0; c < pages_sz; c++) { - pages[c].mem = &ram[c << 12]; + if (mem_size > 1048576) { + if ((c << 12) < (1 << 30)) + pages[c].mem = &ram[c << 12]; + else + pages[c].mem = &ram2[(c << 12) - (1 << 30)]; + } else + pages[c].mem = &ram[c << 12]; if (c < m) { pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; @@ -2420,16 +2658,11 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); memset(&base_mapping, 0x00, sizeof(base_mapping)); memset(_mem_state, 0x00, sizeof(_mem_state)); - /* Set SMM states to (MEM_READ_NORMAL | MEM_WRITE_NORMAL). */ - for (c = 0; c < MEM_MAPPINGS_NO; c++) - _mem_state[c] |= 0x4400; - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - /* mem_set_mem_state(0x0c0000, 0x40000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); */ - mem_set_mem_state(0x0a0000, 0x60000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state_both(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(0x0a0000, 0x60000, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, @@ -2439,21 +2672,38 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); if (mem_size > 1024) { if (cpu_16bitbus && mem_size > 16256) { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(0x100000, (16256 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram,mem_read_ramw,mem_read_raml, mem_write_ram,mem_write_ramw,mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); } else { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, - ((mem_size - 1024) * 1024), - mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml, - ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + if (mem_size > 1048576) { + mem_set_mem_state_both(0x100000, (1048576 - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((1048576 - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + mem_set_mem_state_both((1 << 30), (mem_size - 1048576) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_2gb_mapping, (1 << 30), + ((mem_size - 1048576) * 1024), + mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram2, MEM_MAPPING_INTERNAL, NULL); + } else { + mem_set_mem_state_both(0x100000, (mem_size - 1024) * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, + ((mem_size - 1024) * 1024), + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } } } @@ -2462,20 +2712,35 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz); mem_read_ram,mem_read_ramw,mem_read_raml, mem_write_ram,mem_write_ramw,mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); */ - if (mem_size > 768) + if (mem_size > 768) { mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram,mem_read_ramw,mem_read_raml, mem_write_ram,mem_write_ramw,mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + } + + mem_mapping_add(&ram_smram_mapping[0], 0xa0000, 0x60000, + mem_read_smram,mem_read_smramw,mem_read_smraml, + mem_write_smram,mem_write_smramw,mem_write_smraml, + ram + 0xa0000, MEM_MAPPING_SMRAM, &(smram[0])); + mem_mapping_add(&ram_smram_mapping[1], 0xa0000, 0x60000, + mem_read_ram,mem_read_ramw,mem_read_raml, + mem_write_ram,mem_write_ramw,mem_write_raml, + ram + 0xa0000, MEM_MAPPING_SMRAM, &(smram[1])); + mem_mapping_disable(&ram_smram_mapping[0]); + mem_mapping_disable(&ram_smram_mapping[1]); mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, mem_read_remapped,mem_read_remappedw,mem_read_remappedl, mem_write_remapped,mem_write_remappedw,mem_write_remappedl, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&ram_remapped_mapping); + mem_mapping_disable(&ram_remapped_mapping); mem_a20_init(); + smram[0].host_base = smram[0].ram_base = 0x00000000; + smram[1].host_base = smram[1].ram_base = 0x00000000; + #ifdef USE_NEW_DYNAREC purgable_page_list_head = 0; purgeable_page_count = 0; @@ -2488,6 +2753,7 @@ mem_init(void) { /* Perform a one-time init. */ ram = rom = NULL; + ram2 = NULL; pages = NULL; #if DYNAMIC_TABLES page_lookup = NULL; @@ -2515,7 +2781,7 @@ mem_init(void) void mem_remap_top(int kb) { - int c; + uint32_t c; uint32_t start = (mem_size >= 1024) ? mem_size : 1024; int offset, size = mem_size - 640; @@ -2545,8 +2811,8 @@ mem_remap_top(int kb) #endif } - mem_set_mem_state(start * 1024, size * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(start * 1024, size * 1024, + MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); diff --git a/src/pci.c b/src/pci.c index 15fcd9f1f..4f5b40f66 100644 --- a/src/pci.c +++ b/src/pci.c @@ -31,8 +31,8 @@ #include <86box/pic.h> #include <86box/mem.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/pci.h> -#include <86box/piix.h> #include <86box/keyboard.h> diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 6600a7c0c..75c63d0b3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -516,7 +516,7 @@ MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \ via_vt82c596b.o $(VNCOBJ) -INTELOBJ := intel_flash.o \ +INTELOBJ := intel_flash.o intel_420ex.o \ intel_sio.o intel_piix.o CPUOBJ := cpu.o cpu_table.o \ diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 42caadcbe..7b83f37be 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -520,7 +520,7 @@ MAINOBJ := pc.o config.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \ via_vt82c596b.o $(VNCOBJ) -INTELOBJ := intel_flash.o \ +INTELOBJ := intel_flash.o intel_420ex.o \ intel_sio.o intel_piix.o CPUOBJ := cpu.o cpu_table.o \