Implemented the Intel 420EX combined northbridge and southbridge, added the ASUS PVI-486AP4, and overhauled SMRAM handling (which also implements some previously missing extended SMRAM features of the 440BX+ and VIA Apollo series of chipsets).
This commit is contained in:
@@ -38,7 +38,6 @@ enum
|
|||||||
INTEL_430LX,
|
INTEL_430LX,
|
||||||
INTEL_430NX,
|
INTEL_430NX,
|
||||||
INTEL_430FX,
|
INTEL_430FX,
|
||||||
INTEL_430FX_PB640,
|
|
||||||
INTEL_430HX,
|
INTEL_430HX,
|
||||||
INTEL_430VX,
|
INTEL_430VX,
|
||||||
INTEL_430TX,
|
INTEL_430TX,
|
||||||
@@ -46,14 +45,15 @@ enum
|
|||||||
INTEL_440LX,
|
INTEL_440LX,
|
||||||
INTEL_440EX,
|
INTEL_440EX,
|
||||||
INTEL_440BX,
|
INTEL_440BX,
|
||||||
INTEL_440GX,
|
INTEL_440GX,
|
||||||
INTEL_440ZX
|
INTEL_440ZX
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t pm2_cntrl, max_func,
|
uint8_t pm2_cntrl, max_func,
|
||||||
smram_locked;
|
smram_locked, max_drb,
|
||||||
|
drb_default;
|
||||||
uint8_t regs[2][256], regs_locked[2][256];
|
uint8_t regs[2][256], regs_locked[2][256];
|
||||||
int type;
|
int type;
|
||||||
} i4x0_t;
|
} i4x0_t;
|
||||||
@@ -81,55 +81,28 @@ i4x0_map(uint32_t addr, uint32_t size, int state)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
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_smram(smm, addr, size, is_smram);
|
||||||
|
|
||||||
mem_set_mem_state_common(smm, addr, size, state);
|
|
||||||
flushmmucache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
i4x0_smram_handler_phase0(i4x0_t *dev)
|
i4x0_smram_handler_phase0(i4x0_t *dev)
|
||||||
{
|
{
|
||||||
uint32_t i, n;
|
uint32_t tom = (mem_size << 10);
|
||||||
|
|
||||||
/* Disable any active mappings. */
|
/* Disable any active mappings. */
|
||||||
if (dev->type >= INTEL_430FX) {
|
if (smram[0].host_base != 0x00000000) {
|
||||||
if (dev->type >= INTEL_440LX) {
|
i4x0_smram_map(0, smram[0].host_base, ram_smram_mapping[0].size, 0);
|
||||||
/* Disable high extended SMRAM. */
|
i4x0_smram_map(1, smram[0].host_base, ram_smram_mapping[0].size, 0);
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable TSEG. */
|
if ((dev->type >= INTEL_440BX) && (smram[1].host_base != 0x00000000)) {
|
||||||
i4x0_smram_map(1, ((mem_size << 10) - (1 << 20)), (1 << 20), 1);
|
i4x0_smram_map(1, smram[1].host_base, ram_smram_mapping[1].size, 0);
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable low extended SMRAM. */
|
tom -= (1 << 20);
|
||||||
i4x0_smram_map(0, 0xa0000, 0x20000, 0);
|
mem_set_mem_state_smm(tom, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,20 +111,33 @@ static void
|
|||||||
i4x0_smram_handler_phase1(i4x0_t *dev)
|
i4x0_smram_handler_phase1(i4x0_t *dev)
|
||||||
{
|
{
|
||||||
uint8_t *regs = (uint8_t *) dev->regs[0];
|
uint8_t *regs = (uint8_t *) dev->regs[0];
|
||||||
|
uint32_t tom = (mem_size << 10);
|
||||||
|
|
||||||
uint32_t s, base[2] = { 0x000a0000, 0x00020000 };
|
uint32_t s, base[2] = { 0x000a0000, 0x00020000 };
|
||||||
uint32_t size[2] = { 0, 0 };
|
uint32_t size[2] = { 0, 0 };
|
||||||
|
|
||||||
if (dev->type >= INTEL_430FX) {
|
if (dev->type >= INTEL_430FX) {
|
||||||
/* Set temporary bases and sizes. */
|
/* Set temporary bases and sizes. */
|
||||||
|
smram[0].ram_base = 0x000a0000;
|
||||||
if ((dev->type >= INTEL_440BX) && (regs[0x73] & 0x80)) {
|
if ((dev->type >= INTEL_440BX) && (regs[0x73] & 0x80)) {
|
||||||
base[0] = 0x100a0000;
|
base[0] = 0x100a0000;
|
||||||
size[0] = 0x00060000;
|
size[0] = 0x00060000;
|
||||||
|
smram[0].host_base = 0x100a0000;
|
||||||
} else {
|
} else {
|
||||||
base[0] = 0x000a0000;
|
if (((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) && ((regs[0x72] & 0x07) == 0x04)) {
|
||||||
size[0] = 0x00020000;
|
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. */
|
/* 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));
|
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 (dev->type >= INTEL_440BX) {
|
||||||
if ((regs[0x72] & 0x08) && (regs[0x73] & 0x01)) {
|
if ((regs[0x72] & 0x08) && (regs[0x73] & 0x01)) {
|
||||||
size[1] = (1 << (17 + ((regs[0x73] >> 1) & 0x03)));
|
size[1] = (1 << (17 + ((regs[0x73] >> 1) & 0x03)));
|
||||||
base[1] = (mem_size << 10) - size[1];
|
tom -= size[1];
|
||||||
|
base[1] = tom;
|
||||||
} else
|
} else
|
||||||
base[1] = size[1] = 0x00000000;
|
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
|
} else
|
||||||
base[1] = size[1] = 0x00000000;
|
base[1] = size[1] = 0x00000000;
|
||||||
} else {
|
} else {
|
||||||
@@ -204,6 +205,8 @@ i4x0_smram_handler_phase1(i4x0_t *dev)
|
|||||||
/* If we are not closed, point to RAM. */
|
/* 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:
|
default:
|
||||||
regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42);
|
regs[0x04] = (regs[0x04] & ~0x42) | (val & 0x42);
|
||||||
break;
|
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:
|
case INTEL_440FX: case INTEL_440LX: case INTEL_440EX:
|
||||||
regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02);
|
regs[0x04] = (regs[0x04] & ~0x02) | (val & 0x02);
|
||||||
break;
|
break;
|
||||||
@@ -280,7 +283,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
default:
|
default:
|
||||||
regs[0x07] &= ~(val & 0x70);
|
regs[0x07] &= ~(val & 0x70);
|
||||||
break;
|
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:
|
case INTEL_440LX: case INTEL_440EX:
|
||||||
regs[0x07] &= ~(val & 0x30);
|
regs[0x07] &= ~(val & 0x30);
|
||||||
break;
|
break;
|
||||||
@@ -304,7 +307,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
break;
|
break;
|
||||||
case 0x0f:
|
case 0x0f:
|
||||||
switch (dev->type) {
|
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);
|
regs[0x0f] = (val & 0x40);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -365,7 +368,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case INTEL_430NX:
|
case INTEL_430NX:
|
||||||
regs[0x50] = (val & 0xe7);
|
regs[0x50] = (val & 0xe7);
|
||||||
break;
|
break;
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
case INTEL_430FX:
|
||||||
regs[0x50] = (val & 0xef);
|
regs[0x50] = (val & 0xef);
|
||||||
break;
|
break;
|
||||||
case INTEL_430HX:
|
case INTEL_430HX:
|
||||||
@@ -420,8 +423,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case 0x52: /* Cache Control Register */
|
case 0x52: /* Cache Control Register */
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
case INTEL_420TX: case INTEL_420ZX:
|
case INTEL_420TX: case INTEL_420ZX:
|
||||||
case INTEL_430LX:
|
case INTEL_430LX: case INTEL_430FX:
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
|
||||||
case INTEL_430VX: case INTEL_430TX:
|
case INTEL_430VX: case INTEL_430TX:
|
||||||
default:
|
default:
|
||||||
regs[0x52] = (val & 0xfb);
|
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:
|
case INTEL_430NX: case INTEL_440EX:
|
||||||
regs[0x57] = val;
|
regs[0x57] = val;
|
||||||
break;
|
break;
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
case INTEL_430FX: case INTEL_430HX:
|
||||||
case INTEL_430HX: case INTEL_430VX:
|
case INTEL_430VX:
|
||||||
regs[0x57] = val & 0xcf;
|
regs[0x57] = val & 0xcf;
|
||||||
break;
|
break;
|
||||||
case INTEL_430TX:
|
case INTEL_430TX:
|
||||||
@@ -547,8 +549,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case INTEL_440BX: case INTEL_440ZX:
|
case INTEL_440BX: case INTEL_440ZX:
|
||||||
regs[0x58] = val & 0x03;
|
regs[0x58] = val & 0x03;
|
||||||
break;
|
break;
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
case INTEL_430FX: case INTEL_440FX:
|
||||||
case INTEL_440FX:
|
|
||||||
regs[0x58] = val & 0x7f;
|
regs[0x58] = val & 0x7f;
|
||||||
break;
|
break;
|
||||||
case INTEL_430HX: case INTEL_430VX:
|
case INTEL_430HX: case INTEL_430VX:
|
||||||
@@ -629,8 +630,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
default:
|
default:
|
||||||
regs[addr] = val;
|
regs[addr] = val;
|
||||||
break;
|
break;
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
case INTEL_430FX: case INTEL_430VX:
|
||||||
case INTEL_430VX:
|
|
||||||
regs[addr] = val & 0x3f;
|
regs[addr] = val & 0x3f;
|
||||||
break;
|
break;
|
||||||
case INTEL_430TX:
|
case INTEL_430TX:
|
||||||
@@ -690,7 +690,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
case INTEL_430VX: case INTEL_430TX:
|
case INTEL_430VX: case INTEL_430TX:
|
||||||
regs[0x68] = val;
|
regs[0x68] = val;
|
||||||
break;
|
break;
|
||||||
case INTEL_430FX: case INTEL_430FX_PB640:
|
case INTEL_430FX:
|
||||||
regs[0x68] = val & 0x1f;
|
regs[0x68] = val & 0x1f;
|
||||||
break;
|
break;
|
||||||
case INTEL_440FX: case INTEL_440LX:
|
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)
|
if (dev->smram_locked)
|
||||||
regs[0x72] = (regs[0x72] & 0xdf) | (val & 0x20);
|
regs[0x72] = (regs[0x72] & 0xdf) | (val & 0x20);
|
||||||
else {
|
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);
|
dev->smram_locked = (val & 0x10);
|
||||||
if (dev->smram_locked)
|
if (dev->smram_locked)
|
||||||
regs[0x72] &= 0xbf;
|
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);
|
regs[0x72] = (regs[0x72] & 0xc0) | (val & 0x3f);
|
||||||
dev->smram_locked = (val & 0x08);
|
dev->smram_locked = (val & 0x08);
|
||||||
if (dev->smram_locked)
|
if (dev->smram_locked)
|
||||||
regs[0x72] &= 0xef;
|
regs[0x72] &= 0xdf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i4x0_smram_handler_phase1(dev);
|
i4x0_smram_handler_phase1(dev);
|
||||||
@@ -1225,10 +1228,16 @@ i4x0_reset(void *priv)
|
|||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
i4x0_write(0, 0x5a + i, 0x00, priv);
|
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);
|
i4x0_write(0, 0x72, 0x02, priv);
|
||||||
else
|
} else {
|
||||||
|
dev->regs[0][0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */
|
||||||
i4x0_write(0, 0x72, 0x00, priv);
|
i4x0_write(0, 0x72, 0x00, priv);
|
||||||
|
}
|
||||||
|
|
||||||
if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) {
|
if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440BX) || (dev->type == INTEL_440ZX)) {
|
||||||
for (i = 0; i <= dev->max_func; i++)
|
for (i = 0; i <= dev->max_func; i++)
|
||||||
@@ -1291,6 +1300,8 @@ static void
|
|||||||
regs[0x57] = 0x31;
|
regs[0x57] = 0x31;
|
||||||
regs[0x59] = 0x0f;
|
regs[0x59] = 0x0f;
|
||||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
|
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
|
||||||
|
dev->max_drb = 5;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_430LX:
|
case INTEL_430LX:
|
||||||
regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */
|
regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */
|
||||||
@@ -1307,6 +1318,8 @@ static void
|
|||||||
regs[0x57] = 0x31;
|
regs[0x57] = 0x31;
|
||||||
regs[0x59] = 0x0f;
|
regs[0x59] = 0x0f;
|
||||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
|
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = 0x02;
|
||||||
|
dev->max_drb = 5;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_430NX:
|
case INTEL_430NX:
|
||||||
regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */
|
regs[0x02] = 0xa3; regs[0x03] = 0x04; /* 82434LX/NX */
|
||||||
@@ -1325,12 +1338,12 @@ static void
|
|||||||
regs[0x57] = 0x31;
|
regs[0x57] = 0x31;
|
||||||
regs[0x59] = 0x0f;
|
regs[0x59] = 0x0f;
|
||||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
|
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;
|
break;
|
||||||
case INTEL_430FX_PB640:
|
|
||||||
regs[0x08] = 0x02;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case INTEL_430FX:
|
case INTEL_430FX:
|
||||||
regs[0x02] = 0x2d; regs[0x03] = 0x12; /* SB82437FX-66 */
|
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 */
|
regs[0x52] = 0xb2; /* 512 kB PLB cache, set to 0x42 for 256 kB */
|
||||||
if (cpu_busspeed <= 50000000)
|
if (cpu_busspeed <= 50000000)
|
||||||
regs[0x57] |= 0x01;
|
regs[0x57] |= 0x01;
|
||||||
@@ -1340,6 +1353,8 @@ static void
|
|||||||
regs[0x57] |= 0x03;
|
regs[0x57] |= 0x03;
|
||||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02;
|
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = 0x02;
|
||||||
regs[0x72] = 0x02;
|
regs[0x72] = 0x02;
|
||||||
|
dev->max_drb = 4;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_430HX:
|
case INTEL_430HX:
|
||||||
regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */
|
regs[0x02] = 0x50; regs[0x03] = 0x12; /* 82439HX */
|
||||||
@@ -1352,6 +1367,8 @@ static void
|
|||||||
regs[0x57] |= 0x03;
|
regs[0x57] |= 0x03;
|
||||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
|
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
|
||||||
regs[0x72] = 0x02;
|
regs[0x72] = 0x02;
|
||||||
|
dev->max_drb = 7;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_430VX:
|
case INTEL_430VX:
|
||||||
regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */
|
regs[0x02] = 0x30; regs[0x03] = 0x70; /* 82437VX */
|
||||||
@@ -1371,6 +1388,8 @@ static void
|
|||||||
regs[0x72] = 0x02;
|
regs[0x72] = 0x02;
|
||||||
regs[0x74] = 0x0e;
|
regs[0x74] = 0x0e;
|
||||||
regs[0x78] = 0x23;
|
regs[0x78] = 0x23;
|
||||||
|
dev->max_drb = 4;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_430TX:
|
case INTEL_430TX:
|
||||||
regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */
|
regs[0x02] = 0x00; regs[0x03] = 0x71; /* 82439TX */
|
||||||
@@ -1386,6 +1405,8 @@ static void
|
|||||||
regs[0x67] |= 0x80;
|
regs[0x67] |= 0x80;
|
||||||
regs[0x70] = 0x20;
|
regs[0x70] = 0x20;
|
||||||
regs[0x72] = 0x02;
|
regs[0x72] = 0x02;
|
||||||
|
dev->max_drb = 5;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_440FX:
|
case INTEL_440FX:
|
||||||
regs[0x02] = 0x37; regs[0x03] = 0x12; /* 82441FX */
|
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[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
|
||||||
regs[0x71] = 0x10;
|
regs[0x71] = 0x10;
|
||||||
regs[0x72] = 0x02;
|
regs[0x72] = 0x02;
|
||||||
|
dev->max_drb = 7;
|
||||||
|
dev->drb_default = 0x02;
|
||||||
break;
|
break;
|
||||||
case INTEL_440LX:
|
case INTEL_440LX:
|
||||||
dev->max_func = 1;
|
dev->max_func = 1;
|
||||||
@@ -1422,6 +1445,8 @@ static void
|
|||||||
regs[0xa4] = 0x03;
|
regs[0xa4] = 0x03;
|
||||||
regs[0xa5] = 0x02;
|
regs[0xa5] = 0x02;
|
||||||
regs[0xa7] = 0x1f;
|
regs[0xa7] = 0x1f;
|
||||||
|
dev->max_drb = 7;
|
||||||
|
dev->drb_default = 0x01;
|
||||||
break;
|
break;
|
||||||
case INTEL_440EX:
|
case INTEL_440EX:
|
||||||
dev->max_func = 1;
|
dev->max_func = 1;
|
||||||
@@ -1444,6 +1469,8 @@ static void
|
|||||||
regs[0xa4] = 0x03;
|
regs[0xa4] = 0x03;
|
||||||
regs[0xa5] = 0x02;
|
regs[0xa5] = 0x02;
|
||||||
regs[0xa7] = 0x1f;
|
regs[0xa7] = 0x1f;
|
||||||
|
dev->max_drb = 7;
|
||||||
|
dev->drb_default = 0x01;
|
||||||
break;
|
break;
|
||||||
case INTEL_440BX: case INTEL_440ZX:
|
case INTEL_440BX: case INTEL_440ZX:
|
||||||
regs[0x7a] = (info->local >> 8) & 0xff;
|
regs[0x7a] = (info->local >> 8) & 0xff;
|
||||||
@@ -1470,6 +1497,8 @@ static void
|
|||||||
regs[0xa4] = 0x03;
|
regs[0xa4] = 0x03;
|
||||||
regs[0xa5] = 0x02;
|
regs[0xa5] = 0x02;
|
||||||
regs[0xa7] = 0x1f;
|
regs[0xa7] = 0x1f;
|
||||||
|
dev->max_drb = 7;
|
||||||
|
dev->drb_default = 0x01;
|
||||||
break;
|
break;
|
||||||
case INTEL_440GX:
|
case INTEL_440GX:
|
||||||
regs[0x7a] = (info->local >> 8) & 0xff;
|
regs[0x7a] = (info->local >> 8) & 0xff;
|
||||||
@@ -1493,6 +1522,8 @@ static void
|
|||||||
regs[0xa4] = 0x03;
|
regs[0xa4] = 0x03;
|
||||||
regs[0xa5] = 0x02;
|
regs[0xa5] = 0x02;
|
||||||
regs[0xa7] = 0x1f;
|
regs[0xa7] = 0x1f;
|
||||||
|
dev->max_drb = 7;
|
||||||
|
dev->drb_default = 0x01;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1632,7 +1663,7 @@ const device_t i430fx_pb640_device =
|
|||||||
{
|
{
|
||||||
"Intel SB82437FX-66 (PB640)",
|
"Intel SB82437FX-66 (PB640)",
|
||||||
DEVICE_PCI,
|
DEVICE_PCI,
|
||||||
INTEL_430FX_PB640,
|
0x0200 | INTEL_430FX,
|
||||||
i4x0_init,
|
i4x0_init,
|
||||||
i4x0_close,
|
i4x0_close,
|
||||||
i4x0_reset,
|
i4x0_reset,
|
||||||
|
|||||||
@@ -64,20 +64,12 @@ apollo_map(uint32_t addr, uint32_t size, int state)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
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)
|
mem_set_mem_state_smram_ex(smm, addr, size, is_smram & 0x03);
|
||||||
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);
|
|
||||||
flushmmucache();
|
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)
|
if ((dev->pci_conf[0][0x63] ^ val) & 0xc0)
|
||||||
apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
|
apollo_map(0xe0000, 0x10000, (val & 0xc0) >> 6);
|
||||||
dev->pci_conf[0][0x63] = val;
|
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) {
|
if (dev->id == 0x0691) switch (val & 0x03) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
default:
|
default:
|
||||||
@@ -310,9 +308,9 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
/* Reserved */
|
/* Reserved */
|
||||||
apollo_smram_map(1, 0x000a0000, 0x00020000, 3);
|
apollo_smram_map(1, 0x000a0000, 0x00020000, 3);
|
||||||
if (dev->id == 0x0597) {
|
if (dev->id == 0x0597) {
|
||||||
/* TODO: SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx
|
/* SMI 3xxxx-4xxxx redirect to Axxxx-Bxxxx. */
|
||||||
(this needs a 3xxxx-4xxxx mapping set to EXTERNAL). */
|
smram[0].host_base = 0x00030000;
|
||||||
apollo_smram_map(1, 0x00030000, 0x00020000, 3);
|
apollo_smram_map(1, 0x00030000, 0x00020000, 1);
|
||||||
}
|
}
|
||||||
apollo_smram_map(0, 0x000a0000, 0x00020000, 3);
|
apollo_smram_map(0, 0x000a0000, 0x00020000, 3);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -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);
|
mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mem_size > 1048576)
|
if (mem_size > 2097152)
|
||||||
mem_size = 1048576;
|
mem_size = 2097152;
|
||||||
|
|
||||||
cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0);
|
cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0);
|
||||||
|
|
||||||
|
|||||||
15
src/include/86box/intel_420ex.h
Normal file
15
src/include/86box/intel_420ex.h
Normal file
@@ -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, <mgrca8@gmail.com>
|
||||||
|
* Copyright 2020 Miran Grca.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern const device_t i420ex_device;
|
||||||
@@ -241,6 +241,7 @@ extern int machine_at_alfredo_init(const machine_t *);
|
|||||||
#if defined(DEV_BRANCH) && defined(NO_SIO)
|
#if defined(DEV_BRANCH) && defined(NO_SIO)
|
||||||
extern int machine_at_486sp3g_init(const machine_t *);
|
extern int machine_at_486sp3g_init(const machine_t *);
|
||||||
#endif
|
#endif
|
||||||
|
extern int machine_at_486ap4_init(const machine_t *);
|
||||||
|
|
||||||
/* m_at_commodore.c */
|
/* m_at_commodore.c */
|
||||||
extern int machine_at_cmdpc_init(const machine_t *);
|
extern int machine_at_cmdpc_init(const machine_t *);
|
||||||
|
|||||||
@@ -27,31 +27,45 @@
|
|||||||
#define MEM_MAPPING_ROM 4 /* Executing from ROM may involve
|
#define MEM_MAPPING_ROM 4 /* Executing from ROM may involve
|
||||||
* additional wait states. */
|
* additional wait states. */
|
||||||
#define MEM_MAPPING_ROMCS 8 /* respond to ROMCS* */
|
#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_SHADOW_RAM_MASK 1
|
||||||
#define MEM_MAP_TO_RAM_ADDR_MASK 2
|
#define MEM_MAP_TO_RAM_ADDR_MASK 2
|
||||||
|
|
||||||
#define MEM_READ_ANY 0x00
|
/* _mem_state layout:
|
||||||
#define MEM_READ_INTERNAL 0x10
|
Bits 0 - 7: Normal write
|
||||||
#define MEM_READ_EXTERNAL 0x20
|
Bits 8 -15: Normal read
|
||||||
#define MEM_READ_DISABLED 0x30
|
Bits 16 -23: SMM write
|
||||||
#define MEM_READ_NORMAL 0x40 /* SMM only - means use the non-SMM state */
|
Bits 24 -31: SMM read
|
||||||
#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
|
|
||||||
|
|
||||||
#define MEM_WRITE_ANY 0x00
|
#define MEM_READ_ANY 0x0000
|
||||||
#define MEM_WRITE_INTERNAL 0x01
|
#define MEM_READ_INTERNAL 0x0100
|
||||||
#define MEM_WRITE_EXTERNAL 0x02
|
#define MEM_READ_EXTERNAL 0x0200
|
||||||
#define MEM_WRITE_DISABLED 0x03
|
#define MEM_READ_DISABLED 0x0300
|
||||||
#define MEM_WRITE_NORMAL 0x04 /* SMM only - means use the non-SMM state */
|
#define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */
|
||||||
#define MEM_WRITE_EXTERNAL_EX 0x05
|
#define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */
|
||||||
#define MEM_WRITE_ROMCS 0x06 /* EXTERNAL type + ROMC flag */
|
#define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */
|
||||||
#define MEM_WRITE_EXTANY 0x07 /* Any EXTERNAL type */
|
#define MEM_READ_EXTANY 0x0700 /* Any EXTERNAL type */
|
||||||
#define MEM_WRITE_MASK 0x0f
|
#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
|
/* #define's for memory granularity, currently 16k, but may
|
||||||
change in the future - 4k works, less does not because of
|
change in the future - 4k works, less does not because of
|
||||||
@@ -162,7 +176,14 @@ typedef struct _page_ {
|
|||||||
#endif
|
#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 uint32_t rammask;
|
||||||
|
|
||||||
extern uint8_t *rom;
|
extern uint8_t *rom;
|
||||||
@@ -185,6 +206,8 @@ extern mem_mapping_t base_mapping,
|
|||||||
#endif
|
#endif
|
||||||
ram_remapped_mapping,
|
ram_remapped_mapping,
|
||||||
ram_high_mapping,
|
ram_high_mapping,
|
||||||
|
ram_2gb_mapping,
|
||||||
|
ram_smram_mapping[2],
|
||||||
bios_mapping,
|
bios_mapping,
|
||||||
bios_high_mapping;
|
bios_high_mapping;
|
||||||
|
|
||||||
@@ -193,7 +216,8 @@ extern uint32_t mem_logical_addr;
|
|||||||
extern page_t *pages,
|
extern page_t *pages,
|
||||||
**page_lookup;
|
**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,
|
extern int shadowbios,
|
||||||
shadowbios_write;
|
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_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(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_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 uint8_t mem_readb_phys(uint32_t addr);
|
||||||
extern uint16_t mem_readw_phys(uint32_t addr);
|
extern uint16_t mem_readw_phys(uint32_t addr);
|
||||||
extern uint32_t mem_readl_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_ramw(uint32_t addr, uint16_t val, void *priv);
|
||||||
extern void mem_write_raml(uint32_t addr, uint32_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 uint8_t mem_read_bios(uint32_t addr, void *priv);
|
||||||
extern uint16_t mem_read_biosw(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);
|
extern uint32_t mem_read_biosl(uint32_t addr, void *priv);
|
||||||
|
|||||||
564
src/intel_420ex.c
Normal file
564
src/intel_420ex.c
Normal file
@@ -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, <mgrca8@gmail.com>
|
||||||
|
*
|
||||||
|
* Copyright 2020 Miran Grca.
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#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
|
||||||
|
};
|
||||||
@@ -173,7 +173,7 @@ sio_write(int func, int addr, uint8_t val, void *priv)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
dma_alias_remove();
|
dma_alias_remove();
|
||||||
if (val & 0x40)
|
if (!(val & 0x40))
|
||||||
dma_alias_set();
|
dma_alias_set();
|
||||||
} else
|
} else
|
||||||
dev->regs[addr] = (val & 0x3f);
|
dev->regs[addr] = (val & 0x3f);
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <86box/video.h>
|
#include <86box/video.h>
|
||||||
#include <86box/intel_flash.h>
|
#include <86box/intel_flash.h>
|
||||||
#include <86box/sst_flash.h>
|
#include <86box/sst_flash.h>
|
||||||
|
#include <86box/intel_420ex.h>
|
||||||
#include <86box/intel_sio.h>
|
#include <86box/intel_sio.h>
|
||||||
#include <86box/scsi_ncr53c8xx.h>
|
#include <86box/scsi_ncr53c8xx.h>
|
||||||
#include <86box/machine.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(&sio_device); /* Site says it has a ZB, but the BIOS is designed for an IB. */
|
||||||
device_add(&pc87306_device); /*PC87332*/
|
device_add(&pc87306_device); /*PC87332*/
|
||||||
device_add(&sst_flash_29ee010_device);
|
device_add(&sst_flash_29ee010_device);
|
||||||
device_add(&ncr53c810_pci_device);
|
|
||||||
|
|
||||||
device_add(&i420zx_device);
|
device_add(&i420zx_device);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ const machine_t machines[] = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 486 machines which utilize the PCI bus */
|
/* 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)
|
#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 },
|
{ "[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
|
#endif
|
||||||
@@ -313,8 +314,7 @@ const machine_t machines[] = {
|
|||||||
|
|
||||||
/* Slot 2 machines */
|
/* Slot 2 machines */
|
||||||
/* 440GX */
|
/* 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, 2048, 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, 1024, 16, 511, machine_at_6gxu_init, NULL },
|
|
||||||
|
|
||||||
/* PGA370 machines */
|
/* PGA370 machines */
|
||||||
/* 440LX */
|
/* 440LX */
|
||||||
|
|||||||
380
src/mem.c
380
src/mem.c
@@ -64,8 +64,10 @@ mem_mapping_t base_mapping,
|
|||||||
#endif
|
#endif
|
||||||
ram_remapped_mapping, /* 640..1024K mapping */
|
ram_remapped_mapping, /* 640..1024K mapping */
|
||||||
ram_high_mapping, /* 1024K+ mapping */
|
ram_high_mapping, /* 1024K+ mapping */
|
||||||
|
ram_2gb_mapping, /* 1024M+ mapping */
|
||||||
ram_remapped_mapping,
|
ram_remapped_mapping,
|
||||||
ram_split_mapping,
|
ram_split_mapping,
|
||||||
|
ram_smram_mapping[2],
|
||||||
bios_mapping,
|
bios_mapping,
|
||||||
bios_high_mapping;
|
bios_high_mapping;
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ page_t *pages, /* RAM page table */
|
|||||||
**page_lookup; /* pagetable lookup */
|
**page_lookup; /* pagetable lookup */
|
||||||
uint32_t pages_sz; /* #pages in table */
|
uint32_t pages_sz; /* #pages in table */
|
||||||
|
|
||||||
uint8_t *ram; /* the virtual RAM */
|
uint8_t *ram, *ram2; /* the virtual RAM */
|
||||||
uint32_t rammask;
|
uint32_t rammask;
|
||||||
|
|
||||||
uint8_t *rom; /* the virtual ROM */
|
uint8_t *rom; /* the virtual ROM */
|
||||||
@@ -102,6 +104,8 @@ int cachesize = 256;
|
|||||||
uint32_t get_phys_virt,
|
uint32_t get_phys_virt,
|
||||||
get_phys_phys;
|
get_phys_phys;
|
||||||
|
|
||||||
|
smram_t smram[2] = { { 0x000a0000, 0x000a0000 }, { 0x000a0000, 0x000a0000 } };
|
||||||
|
|
||||||
int mem_a20_key = 0,
|
int mem_a20_key = 0,
|
||||||
mem_a20_alt = 0,
|
mem_a20_alt = 0,
|
||||||
mem_a20_state = 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 *read_mapping[MEM_MAPPINGS_NO];
|
||||||
static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO];
|
||||||
static uint8_t *_mem_exec[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 FIXME
|
||||||
#if (MEM_GRANULARITY_BITS >= 12)
|
#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];
|
page_t *page_target = &pages[addr >> 12];
|
||||||
int c;
|
int c;
|
||||||
|
uint32_t a;
|
||||||
|
|
||||||
for (c = 0; c < 256; c++) {
|
for (c = 0; c < 256; c++) {
|
||||||
if (writelookup[c] != (int) 0xffffffff) {
|
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) {
|
if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) {
|
||||||
writelookup2[writelookup[c]] = -1;
|
writelookup2[writelookup[c]] = -1;
|
||||||
@@ -562,6 +573,8 @@ mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len)
|
|||||||
void
|
void
|
||||||
addreadlookup(uint32_t virt, uint32_t phys)
|
addreadlookup(uint32_t virt, uint32_t phys)
|
||||||
{
|
{
|
||||||
|
uint32_t a;
|
||||||
|
|
||||||
if (virt == 0xffffffff) return;
|
if (virt == 0xffffffff) return;
|
||||||
|
|
||||||
if (readlookup2[virt>>12] != (uintptr_t) -1) 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)
|
if (readlookup[readlnext] != (int) 0xffffffff)
|
||||||
readlookup2[readlookup[readlnext]] = -1;
|
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;
|
readlookupp[readlnext] = mmu_perm;
|
||||||
readlookup[readlnext++] = virt >> 12;
|
readlookup[readlnext++] = virt >> 12;
|
||||||
@@ -582,6 +600,8 @@ addreadlookup(uint32_t virt, uint32_t phys)
|
|||||||
void
|
void
|
||||||
addwritelookup(uint32_t virt, uint32_t phys)
|
addwritelookup(uint32_t virt, uint32_t phys)
|
||||||
{
|
{
|
||||||
|
uint32_t a;
|
||||||
|
|
||||||
if (virt == 0xffffffff) return;
|
if (virt == 0xffffffff) return;
|
||||||
|
|
||||||
if (page_lookup[virt >> 12]) return;
|
if (page_lookup[virt >> 12]) return;
|
||||||
@@ -601,8 +621,14 @@ addwritelookup(uint32_t virt, uint32_t phys)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
page_lookup[virt >> 12] = &pages[phys >> 12];
|
page_lookup[virt >> 12] = &pages[phys >> 12];
|
||||||
else
|
else {
|
||||||
writelookup2[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))
|
||||||
|
writelookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)];
|
||||||
|
else
|
||||||
|
writelookup2[virt>>12] = (uintptr_t)&ram[a];
|
||||||
|
}
|
||||||
|
|
||||||
writelookupp[writelnext] = mmu_perm;
|
writelookupp[writelnext] = mmu_perm;
|
||||||
writelookup[writelnext++] = virt >> 12;
|
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
|
#ifdef USE_NEW_DYNAREC
|
||||||
static inline int
|
static inline int
|
||||||
page_index(page_t *p)
|
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
|
static uint8_t
|
||||||
mem_read_remapped(uint32_t addr, void *priv)
|
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
|
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))
|
if (in_smm && ((smm_state & MEM_READ_MASK) != MEM_READ_NORMAL))
|
||||||
state = smm_state;
|
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:
|
case MEM_READ_DISABLED:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case MEM_READ_ANY:
|
case MEM_READ_ANY:
|
||||||
return 1;
|
return !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
/* On external and 0 mappings without ROMCS. */
|
/* On external and 0 mappings without ROMCS. */
|
||||||
case MEM_READ_EXTERNAL:
|
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. */
|
/* On external and 0 mappings with ROMCS. */
|
||||||
case MEM_READ_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. */
|
/* On any external mappings. */
|
||||||
case MEM_READ_EXTANY:
|
case MEM_READ_EXTANY:
|
||||||
return !(flags & MEM_MAPPING_INTERNAL);
|
return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
case MEM_READ_EXTERNAL_EX:
|
case MEM_READ_EXTERNAL_EX:
|
||||||
if (exec)
|
if (exec)
|
||||||
return !(flags & MEM_MAPPING_EXTERNAL);
|
return !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM);
|
||||||
else
|
else
|
||||||
return !(flags & MEM_MAPPING_INTERNAL);
|
return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
case MEM_READ_INTERNAL:
|
case MEM_READ_INTERNAL:
|
||||||
return !(flags & MEM_MAPPING_EXTERNAL);
|
return !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatal("mem_mapping_read_allowed : bad state %x\n", state);
|
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
|
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))
|
if (in_smm && ((smm_state & MEM_WRITE_MASK) != MEM_WRITE_NORMAL))
|
||||||
state = smm_state;
|
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:
|
case MEM_WRITE_DISABLED:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case MEM_WRITE_ANY:
|
case MEM_WRITE_ANY:
|
||||||
return 1;
|
return !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
/* On external and 0 mappings without ROMCS. */
|
/* On external and 0 mappings without ROMCS. */
|
||||||
case MEM_WRITE_EXTERNAL:
|
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. */
|
/* On external and 0 mappings with ROMCS. */
|
||||||
case MEM_WRITE_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. */
|
/* On any external mappings. */
|
||||||
case MEM_WRITE_EXTANY:
|
case MEM_WRITE_EXTANY:
|
||||||
return !(flags & MEM_MAPPING_INTERNAL);
|
return !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
case MEM_WRITE_INTERNAL:
|
case MEM_WRITE_INTERNAL:
|
||||||
return !(flags & MEM_MAPPING_EXTERNAL);
|
return !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatal("mem_mapping_write_allowed : bad state %x\n", state);
|
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) {
|
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
|
||||||
if (smm)
|
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
|
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
|
#ifdef ENABLE_MEM_LOG
|
||||||
if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
|
if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
|
||||||
mem_log("Set mem state for block at %08X to %02X\n", c + base, state);
|
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
|
void
|
||||||
mem_set_mem_state(uint32_t base, uint32_t size, int state)
|
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
|
void
|
||||||
mem_add_bios(void)
|
mem_add_bios(void)
|
||||||
{
|
{
|
||||||
@@ -2260,16 +2478,16 @@ mem_add_bios(void)
|
|||||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||||
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||||
|
|
||||||
mem_set_mem_state(0x0e0000, 0x20000,
|
mem_set_mem_state_both(0x0e0000, 0x20000,
|
||||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||||
} else {
|
} else {
|
||||||
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
|
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
|
||||||
mem_read_bios,mem_read_biosw,mem_read_biosl,
|
mem_read_bios,mem_read_biosw,mem_read_biosl,
|
||||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||||
|
|
||||||
mem_set_mem_state(biosaddr, biosmask + 1,
|
mem_set_mem_state_both(biosaddr, biosmask + 1,
|
||||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AT) {
|
if (AT) {
|
||||||
@@ -2278,8 +2496,8 @@ mem_add_bios(void)
|
|||||||
mem_write_null,mem_write_nullw,mem_write_nulll,
|
mem_write_null,mem_write_nullw,mem_write_nulll,
|
||||||
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
|
||||||
|
|
||||||
mem_set_mem_state(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
|
||||||
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2310,8 +2528,22 @@ mem_reset(void)
|
|||||||
free(ram);
|
free(ram);
|
||||||
ram = NULL;
|
ram = NULL;
|
||||||
}
|
}
|
||||||
ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */
|
if (ram2 != NULL) {
|
||||||
memset(ram, 0x00, m);
|
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.
|
* 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
|
#endif
|
||||||
|
|
||||||
for (c = 0; c < pages_sz; c++) {
|
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) {
|
if (c < m) {
|
||||||
pages[c].write_b = mem_write_ramb_page;
|
pages[c].write_b = mem_write_ramb_page;
|
||||||
pages[c].write_w = mem_write_ramw_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(&base_mapping, 0x00, sizeof(base_mapping));
|
||||||
|
|
||||||
memset(_mem_state, 0x00, sizeof(_mem_state));
|
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_set_mem_state_both(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024,
|
||||||
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
/* mem_set_mem_state(0x0c0000, 0x40000,
|
mem_set_mem_state_both(0x0a0000, 0x60000,
|
||||||
MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); */
|
MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||||
mem_set_mem_state(0x0a0000, 0x60000,
|
|
||||||
MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
|
||||||
|
|
||||||
mem_mapping_add(&ram_low_mapping, 0x00000,
|
mem_mapping_add(&ram_low_mapping, 0x00000,
|
||||||
(mem_size > 640) ? 0xa0000 : mem_size * 1024,
|
(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 (mem_size > 1024) {
|
||||||
if (cpu_16bitbus && mem_size > 16256) {
|
if (cpu_16bitbus && mem_size > 16256) {
|
||||||
mem_set_mem_state(0x100000, (16256 - 1024) * 1024,
|
mem_set_mem_state_both(0x100000, (16256 - 1024) * 1024,
|
||||||
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
mem_mapping_add(&ram_high_mapping, 0x100000,
|
mem_mapping_add(&ram_high_mapping, 0x100000,
|
||||||
((16256 - 1024) * 1024),
|
((16256 - 1024) * 1024),
|
||||||
mem_read_ram,mem_read_ramw,mem_read_raml,
|
mem_read_ram,mem_read_ramw,mem_read_raml,
|
||||||
mem_write_ram,mem_write_ramw,mem_write_raml,
|
mem_write_ram,mem_write_ramw,mem_write_raml,
|
||||||
ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
|
ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
|
||||||
} else {
|
} else {
|
||||||
mem_set_mem_state(0x100000, (mem_size - 1024) * 1024,
|
if (mem_size > 1048576) {
|
||||||
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
mem_set_mem_state_both(0x100000, (1048576 - 1024) * 1024,
|
||||||
mem_mapping_add(&ram_high_mapping, 0x100000,
|
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
((mem_size - 1024) * 1024),
|
mem_mapping_add(&ram_high_mapping, 0x100000,
|
||||||
mem_read_ram,mem_read_ramw,mem_read_raml,
|
((1048576 - 1024) * 1024),
|
||||||
mem_write_ram,mem_write_ramw,mem_write_raml,
|
mem_read_ram,mem_read_ramw,mem_read_raml,
|
||||||
ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
|
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,11 +2712,23 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
|||||||
mem_read_ram,mem_read_ramw,mem_read_raml,
|
mem_read_ram,mem_read_ramw,mem_read_raml,
|
||||||
mem_write_ram,mem_write_ramw,mem_write_raml,
|
mem_write_ram,mem_write_ramw,mem_write_raml,
|
||||||
ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); */
|
ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); */
|
||||||
if (mem_size > 768)
|
if (mem_size > 768) {
|
||||||
mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000,
|
mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000,
|
||||||
mem_read_ram,mem_read_ramw,mem_read_raml,
|
mem_read_ram,mem_read_ramw,mem_read_raml,
|
||||||
mem_write_ram,mem_write_ramw,mem_write_raml,
|
mem_write_ram,mem_write_ramw,mem_write_raml,
|
||||||
ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
|
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_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
|
||||||
mem_read_remapped,mem_read_remappedw,mem_read_remappedl,
|
mem_read_remapped,mem_read_remappedw,mem_read_remappedl,
|
||||||
@@ -2476,6 +2738,9 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
|
|||||||
|
|
||||||
mem_a20_init();
|
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
|
#ifdef USE_NEW_DYNAREC
|
||||||
purgable_page_list_head = 0;
|
purgable_page_list_head = 0;
|
||||||
purgeable_page_count = 0;
|
purgeable_page_count = 0;
|
||||||
@@ -2488,6 +2753,7 @@ mem_init(void)
|
|||||||
{
|
{
|
||||||
/* Perform a one-time init. */
|
/* Perform a one-time init. */
|
||||||
ram = rom = NULL;
|
ram = rom = NULL;
|
||||||
|
ram2 = NULL;
|
||||||
pages = NULL;
|
pages = NULL;
|
||||||
#if DYNAMIC_TABLES
|
#if DYNAMIC_TABLES
|
||||||
page_lookup = NULL;
|
page_lookup = NULL;
|
||||||
@@ -2515,7 +2781,7 @@ mem_init(void)
|
|||||||
void
|
void
|
||||||
mem_remap_top(int kb)
|
mem_remap_top(int kb)
|
||||||
{
|
{
|
||||||
int c;
|
uint32_t c;
|
||||||
uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
|
uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
|
||||||
int offset, size = mem_size - 640;
|
int offset, size = mem_size - 640;
|
||||||
|
|
||||||
@@ -2545,8 +2811,8 @@ mem_remap_top(int kb)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_set_mem_state(start * 1024, size * 1024,
|
mem_set_mem_state_both(start * 1024, size * 1024,
|
||||||
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||||
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
|
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
|
||||||
mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024));
|
mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024));
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
#include <86box/pic.h>
|
#include <86box/pic.h>
|
||||||
#include <86box/mem.h>
|
#include <86box/mem.h>
|
||||||
#include <86box/device.h>
|
#include <86box/device.h>
|
||||||
|
#include <86box/dma.h>
|
||||||
#include <86box/pci.h>
|
#include <86box/pci.h>
|
||||||
#include <86box/piix.h>
|
|
||||||
#include <86box/keyboard.h>
|
#include <86box/keyboard.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 \
|
usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
|
||||||
via_vt82c596b.o $(VNCOBJ)
|
via_vt82c596b.o $(VNCOBJ)
|
||||||
|
|
||||||
INTELOBJ := intel_flash.o \
|
INTELOBJ := intel_flash.o intel_420ex.o \
|
||||||
intel_sio.o intel_piix.o
|
intel_sio.o intel_piix.o
|
||||||
|
|
||||||
CPUOBJ := cpu.o cpu_table.o \
|
CPUOBJ := cpu.o cpu_table.o \
|
||||||
|
|||||||
@@ -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 \
|
usb.o device.o nvr.o nvr_at.o nvr_ps2.o sst_flash.o via_vt82c586b.o \
|
||||||
via_vt82c596b.o $(VNCOBJ)
|
via_vt82c596b.o $(VNCOBJ)
|
||||||
|
|
||||||
INTELOBJ := intel_flash.o \
|
INTELOBJ := intel_flash.o intel_420ex.o \
|
||||||
intel_sio.o intel_piix.o
|
intel_sio.o intel_piix.o
|
||||||
|
|
||||||
CPUOBJ := cpu.o cpu_table.o \
|
CPUOBJ := cpu.o cpu_table.o \
|
||||||
|
|||||||
Reference in New Issue
Block a user