Merge branch 'master' into opengl

This commit is contained in:
ts-korhonen
2021-04-23 16:14:45 +03:00
11 changed files with 465 additions and 560 deletions

View File

@@ -726,6 +726,8 @@ pc_reset_hard_close(void)
closeal(); closeal();
video_reset_close(); video_reset_close();
cpu_close();
} }
@@ -981,56 +983,56 @@ pc_onesec(void)
void void
set_screen_size(int x, int y) set_screen_size(int x, int y)
{ {
int owsx = scrnsz_x; int owsx = scrnsz_x;
int owsy = scrnsz_y; int owsy = scrnsz_y;
int temp_overscan_x = overscan_x; int temp_overscan_x = overscan_x;
int temp_overscan_y = overscan_y; int temp_overscan_y = overscan_y;
double dx, dy, dtx, dty; double dx, dy, dtx, dty;
/* Make sure we keep usable values. */ /* Make sure we keep usable values. */
#if 0 #if 0
pc_log("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize); pc_log("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize);
#endif #endif
if (x < 320) x = 320; if (x < 320) x = 320;
if (y < 200) y = 200; if (y < 200) y = 200;
if (x > 2048) x = 2048; if (x > 2048) x = 2048;
if (y > 2048) y = 2048; if (y > 2048) y = 2048;
/* Save the new values as "real" (unscaled) resolution. */ /* Save the new values as "real" (unscaled) resolution. */
unscaled_size_x = x; unscaled_size_x = x;
efscrnsz_y = y; efscrnsz_y = y;
if (suppress_overscan) if (suppress_overscan)
temp_overscan_x = temp_overscan_y = 0; temp_overscan_x = temp_overscan_y = 0;
if (force_43) { if (force_43) {
dx = (double)x; dx = (double)x;
dtx = (double)temp_overscan_x; dtx = (double)temp_overscan_x;
dy = (double)y; dy = (double)y;
dty = (double)temp_overscan_y; dty = (double)temp_overscan_y;
/* Account for possible overscan. */ /* Account for possible overscan. */
if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) { if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) {
/* CGA */ /* CGA */
dy = (((dx - dtx) / 4.0) * 3.0) + dty; dy = (((dx - dtx) / 4.0) * 3.0) + dty;
} else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) { } else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) {
/* MDA/Hercules */ /* MDA/Hercules */
dy = (x / 4.0) * 3.0; dy = (x / 4.0) * 3.0;
} else { } else {
if (enable_overscan) { if (enable_overscan) {
/* EGA/(S)VGA with overscan */ /* EGA/(S)VGA with overscan */
dy = (((dx - dtx) / 4.0) * 3.0) + dty; dy = (((dx - dtx) / 4.0) * 3.0) + dty;
} else { } else {
/* EGA/(S)VGA without overscan */ /* EGA/(S)VGA without overscan */
dy = (x / 4.0) * 3.0; dy = (x / 4.0) * 3.0;
} }
} }
unscaled_size_y = (int)dy; unscaled_size_y = (int)dy;
} else } else
unscaled_size_y = efscrnsz_y; unscaled_size_y = efscrnsz_y;
switch(scale) { switch(scale) {
case 0: /* 50% */ case 0: /* 50% */
scrnsz_x = (unscaled_size_x>>1); scrnsz_x = (unscaled_size_x>>1);
scrnsz_y = (unscaled_size_y>>1); scrnsz_y = (unscaled_size_y>>1);
@@ -1050,12 +1052,12 @@ set_screen_size(int x, int y)
scrnsz_x = (unscaled_size_x<<1); scrnsz_x = (unscaled_size_x<<1);
scrnsz_y = (unscaled_size_y<<1); scrnsz_y = (unscaled_size_y<<1);
break; break;
} }
/* If the resolution has changed, let the main thread handle it. */ /* If the resolution has changed, let the main thread handle it. */
if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) if ((owsx != scrnsz_x) || (owsy != scrnsz_y))
doresize = 1; doresize = 1;
else else
doresize = 0; doresize = 0;
} }

View File

@@ -124,6 +124,8 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
ret = (dev->regs.pmsts >> shift16) & 0xff; ret = (dev->regs.pmsts >> shift16) & 0xff;
if (addr == 0x01) if (addr == 0x01)
ret |= (acpi_rtc_status << 2); ret |= (acpi_rtc_status << 2);
else
ret |= 0x10;
break; break;
case 0x02: case 0x03: case 0x02: case 0x03:
/* PMEN - Power Management Resume Enable Register (IO) */ /* PMEN - Power Management Resume Enable Register (IO) */
@@ -133,7 +135,7 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
/* PMCNTRL - Power Management Control Register (IO) */ /* PMCNTRL - Power Management Control Register (IO) */
ret = (dev->regs.pmcntrl >> shift16) & 0xff; ret = (dev->regs.pmcntrl >> shift16) & 0xff;
if (addr == 0x05) if (addr == 0x05)
ret = (ret & 0xdf) | 0x02; /* Bit 5 is write-only. */ ret = (ret & 0xdf); /* Bit 5 is write-only. */
break; break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x08: case 0x09: case 0x0a: case 0x0b:
/* PMTMR - Power Management Timer Register (IO) */ /* PMTMR - Power Management Timer Register (IO) */
@@ -152,6 +154,7 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p)
return ret; return ret;
} }
static uint32_t static uint32_t
acpi_reg_read_ali(int size, uint16_t addr, void *p) acpi_reg_read_ali(int size, uint16_t addr, void *p)
{ {
@@ -219,6 +222,7 @@ acpi_reg_read_ali(int size, uint16_t addr, void *p)
return ret; return ret;
} }
static uint32_t static uint32_t
acpi_reg_read_intel(int size, uint16_t addr, void *p) acpi_reg_read_intel(int size, uint16_t addr, void *p)
{ {
@@ -247,7 +251,7 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p)
/* GLBSTS - Global Status Register (IO) */ /* GLBSTS - Global Status Register (IO) */
ret = (dev->regs.glbsts >> shift16) & 0xff; ret = (dev->regs.glbsts >> shift16) & 0xff;
if (addr == 0x18) { if (addr == 0x18) {
ret &= 0x25; ret &= 0x27;
if (dev->regs.gpsts != 0x0000) if (dev->regs.gpsts != 0x0000)
ret |= 0x80; ret |= 0x80;
if (dev->regs.pmsts != 0x0000) if (dev->regs.pmsts != 0x0000)
@@ -288,8 +292,8 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p)
} }
#ifdef ENABLE_ACPI_LOG #ifdef ENABLE_ACPI_LOG
if (size != 1) // if (size != 1)
acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret);
#endif #endif
return ret; return ret;
} }
@@ -635,8 +639,8 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
break; break;
case 0x04: case 0x05: case 0x04: case 0x05:
/* PMCNTRL - Power Management Control Register (IO) */ /* PMCNTRL - Power Management Control Register (IO) */
if ((addr == 0x05) && (dev->regs.pmcntrl & 0x2000)) { if ((addr == 0x05) && (val & 0x20)) {
sus_typ = (dev->regs.pmcntrl >> 10) & 7; sus_typ = (val >> 2) & 7;
switch (sus_typ) { switch (sus_typ) {
case 0: case 0:
/* Soft power off. */ /* Soft power off. */
@@ -662,15 +666,16 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p)
resetx86(); resetx86();
break; break;
default: default:
dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3c07; dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */;
break; break;
} }
} else } else
dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3c07; dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */;
break; break;
} }
} }
static void static void
acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p) acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
{ {
@@ -742,6 +747,7 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *p)
} }
} }
static void static void
acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p) acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
{ {
@@ -765,13 +771,17 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *p)
/* GPEN - General Purpose Enable Register (IO) */ /* GPEN - General Purpose Enable Register (IO) */
dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0f01; dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0f01;
break; break;
case 0x10: case 0x11: case 0x12: case 0x13: case 0x10: case 0x11: case 0x13:
/* PCNTRL - Processor Control Register (IO) */ /* PCNTRL - Processor Control Register (IO) */
dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e; dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e;
break; break;
case 0x12:
/* PCNTRL - Processor Control Register (IO) */
dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xfd << shift32)) | (val << shift32)) & 0x00023e1e;
break;
case 0x18: case 0x19: case 0x18: case 0x19:
/* GLBSTS - Global Status Register (IO) */ /* GLBSTS - Global Status Register (IO) */
dev->regs.glbsts &= ~((val << shift16) & 0x0df7); dev->regs.glbsts &= ~((val << shift16) & 0x0dd7);
break; break;
case 0x1c: case 0x1d: case 0x1e: case 0x1f: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
/* DEVSTS - Device Status Register (IO) */ /* DEVSTS - Device Status Register (IO) */

View File

@@ -250,16 +250,11 @@ neat_log(const char *fmt, ...)
static uint8_t static uint8_t
ems_readb(uint32_t addr, void *priv) ems_readb(uint32_t addr, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; neat_t *dev = (neat_t *)priv;
neat_t *dev = (neat_t *)map->dev;
uint8_t ret = 0xff; uint8_t ret = 0xff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Grab the data. */ /* Grab the data. */
ret = *(uint8_t *)(dev->ems[vpage].addr + (addr - map->base)); ret = *(uint8_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff));
return(ret); return(ret);
} }
@@ -268,16 +263,11 @@ ems_readb(uint32_t addr, void *priv)
static uint16_t static uint16_t
ems_readw(uint32_t addr, void *priv) ems_readw(uint32_t addr, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; neat_t *dev = (neat_t *)priv;
neat_t *dev = (neat_t *)map->dev;
uint16_t ret = 0xffff; uint16_t ret = 0xffff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Grab the data. */ /* Grab the data. */
ret = *(uint16_t *)(dev->ems[vpage].addr + (addr - map->base)); ret = *(uint16_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff));
return(ret); return(ret);
} }
@@ -286,30 +276,20 @@ ems_readw(uint32_t addr, void *priv)
static void static void
ems_writeb(uint32_t addr, uint8_t val, void *priv) ems_writeb(uint32_t addr, uint8_t val, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; neat_t *dev = (neat_t *)priv;
neat_t *dev = (neat_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Write the data. */ /* Write the data. */
*(uint8_t *)(dev->ems[vpage].addr + (addr - map->base)) = val; *(uint8_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff)) = val;
} }
/* Write one word to paged RAM. */ /* Write one word to paged RAM. */
static void static void
ems_writew(uint32_t addr, uint16_t val, void *priv) ems_writew(uint32_t addr, uint16_t val, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; neat_t *dev = (neat_t *)priv;
neat_t *dev = (neat_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Write the data. */ /* Write the data. */
*(uint16_t *)(dev->ems[vpage].addr + (addr - map->base)) = val; *(uint16_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff)) = val;
} }
/* Re-calculate the active-page physical address. */ /* Re-calculate the active-page physical address. */
@@ -436,8 +416,7 @@ ems_init(neat_t *dev, int en)
ems_readb, ems_readw, NULL, ems_readb, ems_readw, NULL,
ems_writeb, ems_writew, NULL, ems_writeb, ems_writew, NULL,
ram, MEM_MAPPING_EXTERNAL, ram, MEM_MAPPING_EXTERNAL,
&dev->ems[i].mapping); dev);
mem_mapping_set_dev(&dev->ems[i].mapping, dev);
/* Disable for now. */ /* Disable for now. */
mem_mapping_disable(&dev->ems[i].mapping); mem_mapping_disable(&dev->ems[i].mapping);

View File

@@ -98,7 +98,7 @@ const OpFn *x86_opcodes, *x86_opcodes_0f,
uint16_t cpu_fast_off_count, cpu_fast_off_val; uint16_t cpu_fast_off_count, cpu_fast_off_val;
uint16_t temp_seg_data[4] = {0, 0, 0, 0}; uint16_t temp_seg_data[4] = {0, 0, 0, 0};
int isa_cycles, int isa_cycles, cpu_inited,
cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l, cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l,
cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles, cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles,
@@ -350,6 +350,8 @@ cpu_family_is_eligible(const cpu_family_t *cpu_family, int machine)
void void
cpu_set(void) cpu_set(void)
{ {
cpu_inited = 1;
cpu_effective = cpu; cpu_effective = cpu;
cpu_s = (CPU *) &cpu_f->cpus[cpu_effective]; cpu_s = (CPU *) &cpu_f->cpus[cpu_effective];
@@ -1365,6 +1367,13 @@ cpu_set(void)
} }
void
cpu_close(void)
{
cpu_inited = 0;
}
void void
cpu_set_isa_speed(int speed) cpu_set_isa_speed(int speed)
{ {

View File

@@ -511,7 +511,7 @@ extern int cgate16;
extern int cpl_override; extern int cpl_override;
extern int CPUID; extern int CPUID;
extern uint64_t xt_cpu_multi; extern uint64_t xt_cpu_multi;
extern int isa_cycles; extern int isa_cycles, cpu_inited;
extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
extern uint32_t pccache; extern uint32_t pccache;
extern uint8_t *pccache2; extern uint8_t *pccache2;
@@ -606,6 +606,7 @@ extern char *cpu_current_pc(char *bufp);
extern void cpu_update_waitstates(void); extern void cpu_update_waitstates(void);
extern void cpu_set(void); extern void cpu_set(void);
extern void cpu_close(void);
extern void cpu_set_isa_speed(int speed); extern void cpu_set_isa_speed(int speed);
extern void cpu_set_pci_speed(int speed); extern void cpu_set_pci_speed(int speed);
extern void cpu_set_isa_pci_div(int div); extern void cpu_set_isa_pci_div(int div);

View File

@@ -81,6 +81,8 @@ seg_reset(x86seg *s)
s->limit_low = 0; s->limit_low = 0;
s->limit_high = 0xffff; s->limit_high = 0xffff;
if (s == &cpu_state.seg_cs) { if (s == &cpu_state.seg_cs) {
if (!cpu_inited)
fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n");
s->base = AT ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; s->base = AT ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0;
s->seg = AT ? 0xf000 : 0xffff; s->seg = AT ? 0xf000 : 0xffff;
} else { } else {

View File

@@ -103,6 +103,11 @@ typedef struct {
mem_mapping_t mapping; /* mapping entry for page */ mem_mapping_t mapping; /* mapping entry for page */
} emsreg_t; } emsreg_t;
typedef struct {
uint32_t base;
uint8_t *ptr;
} ext_ram_t;
typedef struct { typedef struct {
const char *name; const char *name;
uint8_t board : 6, /* board type */ uint8_t board : 6, /* board type */
@@ -125,6 +130,8 @@ typedef struct {
uint8_t *ram; /* allocated RAM buffer */ uint8_t *ram; /* allocated RAM buffer */
ext_ram_t ext_ram[3]; /* structures for the mappings */
mem_mapping_t low_mapping; /* mapping for low mem */ mem_mapping_t low_mapping; /* mapping for low mem */
mem_mapping_t high_mapping; /* mapping for high mem */ mem_mapping_t high_mapping; /* mapping for high mem */
@@ -151,16 +158,17 @@ isamem_log(const char *fmt, ...)
#endif #endif
/* Why this convoluted setup with the mem_dev stuff when it's much simpler
to just pass the exec pointer as p as well, and then just use that. */
/* Read one byte from onboard RAM. */ /* Read one byte from onboard RAM. */
static uint8_t static uint8_t
ram_readb(uint32_t addr, void *priv) ram_readb(uint32_t addr, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; ext_ram_t *dev = (ext_ram_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
uint8_t ret = 0xff; uint8_t ret = 0xff;
/* Grab the data. */ /* Grab the data. */
ret = *(uint8_t *)(dev->ram + (addr - map->base)); ret = *(uint8_t *)(dev->ptr + (addr - dev->base));
return(ret); return(ret);
} }
@@ -170,12 +178,11 @@ ram_readb(uint32_t addr, void *priv)
static uint16_t static uint16_t
ram_readw(uint32_t addr, void *priv) ram_readw(uint32_t addr, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; ext_ram_t *dev = (ext_ram_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
uint16_t ret = 0xffff; uint16_t ret = 0xffff;
/* Grab the data. */ /* Grab the data. */
ret = *(uint16_t *)(dev->ram + (addr - map->base)); ret = *(uint16_t *)(dev->ptr + (addr - dev->base));
return(ret); return(ret);
} }
@@ -185,11 +192,10 @@ ram_readw(uint32_t addr, void *priv)
static void static void
ram_writeb(uint32_t addr, uint8_t val, void *priv) ram_writeb(uint32_t addr, uint8_t val, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; ext_ram_t *dev = (ext_ram_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
/* Write the data. */ /* Write the data. */
*(uint8_t *)(dev->ram + (addr - map->base)) = val; *(uint8_t *)(dev->ptr + (addr - dev->base)) = val;
} }
@@ -197,11 +203,10 @@ ram_writeb(uint32_t addr, uint8_t val, void *priv)
static void static void
ram_writew(uint32_t addr, uint16_t val, void *priv) ram_writew(uint32_t addr, uint16_t val, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; ext_ram_t *dev = (ext_ram_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
/* Write the data. */ /* Write the data. */
*(uint16_t *)(dev->ram + (addr - map->base)) = val; *(uint16_t *)(dev->ptr + (addr - dev->base)) = val;
} }
@@ -209,18 +214,13 @@ ram_writew(uint32_t addr, uint16_t val, void *priv)
static uint8_t static uint8_t
ems_readb(uint32_t addr, void *priv) ems_readb(uint32_t addr, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; memdev_t *dev = (memdev_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
uint8_t ret = 0xff; uint8_t ret = 0xff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Grab the data. */ /* Grab the data. */
ret = *(uint8_t *)(dev->ems[vpage].addr + (addr - map->base)); ret = *(uint8_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff));
#if ISAMEM_DEBUG #if ISAMEM_DEBUG
if ((addr % 4096)==0) isamem_log("EMS readb(%06x) = %02x\n",addr-map->base,ret); if ((addr % 4096)==0) isamem_log("EMS readb(%06x) = %02x\n",addr-dev&0x3fff,ret);
#endif #endif
return(ret); return(ret);
@@ -231,18 +231,13 @@ ems_readb(uint32_t addr, void *priv)
static uint16_t static uint16_t
ems_readw(uint32_t addr, void *priv) ems_readw(uint32_t addr, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; memdev_t *dev = (memdev_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
uint16_t ret = 0xffff; uint16_t ret = 0xffff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Grab the data. */ /* Grab the data. */
ret = *(uint16_t *)(dev->ems[vpage].addr + (addr - map->base)); ret = *(uint16_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff));
#if ISAMEM_DEBUG #if ISAMEM_DEBUG
if ((addr % 4096)==0) isamem_log("EMS readw(%06x) = %04x\n",addr-map->base,ret); if ((addr % 4096)==0) isamem_log("EMS readw(%06x) = %04x\n",addr-dev&0x3fff,ret);
#endif #endif
return(ret); return(ret);
@@ -253,18 +248,13 @@ ems_readw(uint32_t addr, void *priv)
static void static void
ems_writeb(uint32_t addr, uint8_t val, void *priv) ems_writeb(uint32_t addr, uint8_t val, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; memdev_t *dev = (memdev_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Write the data. */ /* Write the data. */
#if ISAMEM_DEBUG #if ISAMEM_DEBUG
if ((addr % 4096)==0) isamem_log("EMS writeb(%06x, %02x)\n",addr-map->base,val); if ((addr % 4096)==0) isamem_log("EMS writeb(%06x, %02x)\n",addr-dev&0x3fff,val);
#endif #endif
*(uint8_t *)(dev->ems[vpage].addr + (addr - map->base)) = val; *(uint8_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff)) = val;
} }
@@ -272,18 +262,13 @@ ems_writeb(uint32_t addr, uint8_t val, void *priv)
static void static void
ems_writew(uint32_t addr, uint16_t val, void *priv) ems_writew(uint32_t addr, uint16_t val, void *priv)
{ {
mem_mapping_t *map = (mem_mapping_t *)priv; memdev_t *dev = (memdev_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* Write the data. */ /* Write the data. */
#if ISAMEM_DEBUG #if ISAMEM_DEBUG
if ((addr % 4096)==0) isamem_log("EMS writew(%06x, %04x)\n",addr-map->base,val); if ((addr % 4096)==0) isamem_log("EMS writew(%06x, %04x)\n",addr&0x3fff,val);
#endif #endif
*(uint16_t *)(dev->ems[vpage].addr + (addr - map->base)) = val; *(uint16_t *)(dev->ems[((addr & 0xffff) >> 14)].addr + (addr & 0x3fff)) = val;
} }
@@ -509,6 +494,9 @@ dev->frame_addr = 0xE0000;
t = tot; t = tot;
isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10);
dev->ext_ram[0].ptr = ptr;
dev->ext_ram[0].base = addr;
/* Create, initialize and enable the low-memory mapping. */ /* Create, initialize and enable the low-memory mapping. */
mem_mapping_add(&dev->low_mapping, addr, t, mem_mapping_add(&dev->low_mapping, addr, t,
ram_readb, ram_readb,
@@ -517,8 +505,7 @@ dev->frame_addr = 0xE0000;
ram_writeb, ram_writeb,
(dev->flags&FLAG_WIDE) ? ram_writew : NULL, (dev->flags&FLAG_WIDE) ? ram_writew : NULL,
NULL, NULL,
ptr, MEM_MAPPING_EXTERNAL, &dev->low_mapping); ptr, MEM_MAPPING_EXTERNAL, &dev->ext_ram[0]);
mem_mapping_set_dev(&dev->low_mapping, dev);
/* Tell the memory system this is external RAM. */ /* Tell the memory system this is external RAM. */
mem_set_mem_state(addr, t, mem_set_mem_state(addr, t,
@@ -542,16 +529,16 @@ dev->frame_addr = 0xE0000;
isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10);
dev->ext_ram[1].ptr = ptr;
dev->ext_ram[1].base = addr + tot;
/* Update and enable the remap. */ /* Update and enable the remap. */
mem_mapping_del(&ram_remapped_mapping); mem_mapping_set(&ram_remapped_mapping,
mem_mapping_add(&ram_remapped_mapping,
addr + tot, t, addr + tot, t,
ram_readb, ram_readw, NULL, ram_readb, ram_readw, NULL,
ram_writeb, ram_writew, NULL, ram_writeb, ram_writew, NULL,
ptr, MEM_MAPPING_EXTERNAL, ptr, MEM_MAPPING_EXTERNAL,
&ram_remapped_mapping); &dev->ext_ram[1]);
mem_mapping_set_exec(&ram_remapped_mapping, ptr);
mem_mapping_set_dev(&ram_remapped_mapping, dev);
mem_mapping_disable(&ram_remapped_mapping); mem_mapping_disable(&ram_remapped_mapping);
/* Tell the memory system this is external RAM. */ /* Tell the memory system this is external RAM. */
@@ -576,12 +563,14 @@ dev->frame_addr = 0xE0000;
t = tot; t = tot;
isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10);
dev->ext_ram[2].ptr = ptr;
dev->ext_ram[2].base = addr;
/* Create, initialize and enable the high-memory mapping. */ /* Create, initialize and enable the high-memory mapping. */
mem_mapping_add(&dev->high_mapping, addr, t, mem_mapping_add(&dev->high_mapping, addr, t,
ram_readb, ram_readw, NULL, ram_readb, ram_readw, NULL,
ram_writeb, ram_writew, NULL, ram_writeb, ram_writew, NULL,
ptr, MEM_MAPPING_EXTERNAL, &dev->high_mapping); ptr, MEM_MAPPING_EXTERNAL, &dev->ext_ram[2]);
mem_mapping_set_dev(&dev->high_mapping, dev);
/* Tell the memory system this is external RAM. */ /* Tell the memory system this is external RAM. */
mem_set_mem_state(addr, t, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); mem_set_mem_state(addr, t, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
@@ -625,8 +614,7 @@ dev->frame_addr = 0xE0000;
(dev->flags&FLAG_WIDE) ? ems_writew : NULL, (dev->flags&FLAG_WIDE) ? ems_writew : NULL,
NULL, NULL,
ptr, MEM_MAPPING_EXTERNAL, ptr, MEM_MAPPING_EXTERNAL,
&dev->ems[i].mapping); dev);
mem_mapping_set_dev(&dev->ems[i].mapping, dev);
/* For now, disable it. */ /* For now, disable it. */
mem_mapping_disable(&dev->ems[i].mapping); mem_mapping_disable(&dev->ems[i].mapping);

View File

@@ -22,66 +22,93 @@
# define EMU_MEM_H # define EMU_MEM_H
#define MEM_MAPPING_EXTERNAL 1 /* on external bus (ISA/PCI) */
#define MEM_MAPPING_INTERNAL 2 /* on internal bus (RAM) */
#define MEM_MAPPING_ROM 4 /* Executing from ROM may involve
* additional wait states. */
#define MEM_MAPPING_ROMCS 8 /* respond to ROMCS* */
#define MEM_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
/* _mem_state layout: #define STATE_CPU 0
Bits 0 - 7: Normal write #define STATE_BUS 2
Bits 8 -15: Normal read
Bits 16 -23: SMM write
Bits 24 -31: SMM read
*/
#define MEM_READ_DISABLED 0x0000 #define ACCESS_CPU 1 /* Update CPU non-SMM access. */
#define MEM_READ_INTERNAL 0x0100 #define ACCESS_CPU_SMM 2 /* Update CPU SMM access. */
#define MEM_READ_EXTERNAL 0x0200 #define ACCESS_BUS 4 /* Update bus access. */
#define MEM_READ_ANY 0x0300 #define ACCESS_BUS_SMM 8 /* Update bus SMM access. */
#define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */ #define ACCESS_NORMAL 5 /* Update CPU and bus non-SMM accesses. */
#define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */ #define ACCESS_SMM 10 /* Update CPU and bus SMM accesses. */
#define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */ #define ACCESS_CPU_BOTH 3 /* Update CPU non-SMM and SMM accesses. */
#define MEM_READ_EXTANY 0x0700 /* Any EXTERNAL type */ #define ACCESS_BUS_BOTH 12 /* Update bus non-SMM and SMM accesses. */
#define MEM_READ_SMRAM 0x1000 #define ACCESS_ALL 15 /* Update all accesses. */
#define MEM_READ_SMRAM_EX 0x2000
#define MEM_READ_DISABLED_EX 0x4000
#define MEM_READ_MASK 0xff00
#define MEM_WRITE_DISABLED 0x0000 #define ACCESS_INTERNAL 1
#define MEM_WRITE_INTERNAL 0x0001 #define ACCESS_ROMCS 2
#define MEM_WRITE_EXTERNAL 0x0002 #define ACCESS_SMRAM 4
#define MEM_WRITE_ANY 0x0003 #define ACCESS_CACHE 8
#define MEM_WRITE_NORMAL 0x0004 /* SMM only - means use the non-SMM state */ #define ACCESS_DISABLED 16
#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 ACCESS_X_INTERNAL 1
#define ACCESS_X_ROMCS 2
#define ACCESS_X_SMRAM 4
#define ACCESS_X_CACHE 8
#define ACCESS_X_DISABLED 16
#define ACCESS_W_INTERNAL 32
#define ACCESS_W_ROMCS 64
#define ACCESS_W_SMRAM 128
#define ACCESS_W_CACHE 256
#define ACCESS_W_DISABLED 512
#define ACCESS_R_INTERNAL 1024
#define ACCESS_R_ROMCS 2048
#define ACCESS_R_SMRAM 4096
#define ACCESS_R_CACHE 8192
#define ACCESS_R_DISABLED 16384
/* #define's for memory granularity, currently 16k, but may #define ACCESS_EXECUTE 0
change in the future - 4k works, less does not because of #define ACCESS_READ 1
internal 4k pages. */ #define ACCESS_WRITE 2
#ifdef DEFAULT_GRANULARITY
#define MEM_GRANULARITY_BITS 14 /* Conversion #define's - we need these to seamlessly convert the old mem_set_mem_state() calls to
#define MEM_GRANULARITY_SIZE (1 << MEM_GRANULARITY_BITS) the new stuff in order to make this a drop in replacement.
#define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2)
#define MEM_GRANULARITY_QBOUND (MEM_GRANULARITY_SIZE - 4) Read here includes execute access since the old code also used read access for execute access,
#define MEM_GRANULARITY_MASK (MEM_GRANULARITY_SIZE - 1) with some exceptions. */
#define MEM_GRANULARITY_HMASK ((1 << (MEM_GRANULARITY_BITS - 1)) - 1)
#define MEM_GRANULARITY_QMASK ((1 << (MEM_GRANULARITY_BITS - 2)) - 1) #define MEM_READ_DISABLED (ACCESS_X_DISABLED | ACCESS_R_DISABLED)
#define MEM_GRANULARITY_PMASK ((1 << (MEM_GRANULARITY_BITS - 3)) - 1) #define MEM_READ_INTERNAL (ACCESS_X_INTERNAL | ACCESS_R_INTERNAL)
#define MEM_MAPPINGS_NO ((0x100000 >> MEM_GRANULARITY_BITS) << 12) #define MEM_READ_EXTERNAL 0
#define MEM_GRANULARITY_PAGE (MEM_GRANULARITY_MASK & ~0xfff) /* These two are going to be identical - on real hardware, chips that don't care about ROMCS#,
#else are not magically disabled. */
#define MEM_READ_ROMCS (ACCESS_X_ROMCS | ACCESS_R_ROMCS)
#define MEM_READ_EXTANY MEM_READ_ROMCS
/* Internal execute access, external read access. */
#define MEM_READ_EXTERNAL_EX 0
#define MEM_READ_SMRAM (ACCESS_X_SMRAM | ACCESS_R_SMRAM)
#define MEM_READ_SMRAM_EX (ACCESS_X_SMRAM)
/* Theese two are going to be identical. */
#define MEM_READ_DISABLED_EX MEM_READ_DISABLED
#define MEM_READ_MASK 0x7c1f
#define MEM_WRITE_DISABLED (ACCESS_W_DISABLED)
#define MEM_WRITE_INTERNAL (ACCESS_W_INTERNAL)
#define MEM_WRITE_EXTERNAL 0
/* These two are going to be identical - on real hardware, chips that don't care about ROMCS#,
are not magically disabled. */
#define MEM_WRITE_ROMCS (ACCESS_W_ROMCS)
#define MEM_WRITE_EXTANY (ACCESS_W_ROMCS)
#define MEM_WRITE_SMRAM (ACCESS_W_SMRAM)
/* Theese two are going to be identical. */
#define MEM_WRITE_DISABLED_EX MEM_READ_DISABLED
#define MEM_WRITE_MASK 0x03e0
#define MEM_MAPPING_EXTERNAL 1 /* On external bus (ISA/PCI). */
#define MEM_MAPPING_INTERNAL 2 /* On internal bus (RAM). */
#define MEM_MAPPING_ROM_WS 4 /* Executing from ROM may involve additional wait states. */
#define MEM_MAPPING_IS_ROM 8 /* Responds to ROMCS#. */
#define MEM_MAPPING_ROM (MEM_MAPPING_ROM_WS | MEM_MAPPING_IS_ROM)
#define MEM_MAPPING_ROMCS 16 /* If it responds to ROMCS#, it requires ROMCS# asserted. */
#define MEM_MAPPING_SMRAM 32 /* On internal bus (RAM) but SMRAM. */
#define MEM_MAPPING_CACHE 64 /* Cache or MTRR - please avoid such mappings unless
stricly necessary (eg. for CoreBoot). */
/* #define's for memory granularity, currently 4k, less does
not work because of internal 4k pages. */
#define MEM_GRANULARITY_BITS 12 #define MEM_GRANULARITY_BITS 12
#define MEM_GRANULARITY_SIZE (1 << MEM_GRANULARITY_BITS) #define MEM_GRANULARITY_SIZE (1 << MEM_GRANULARITY_BITS)
#define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2) #define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2)
@@ -92,16 +119,39 @@
#define MEM_GRANULARITY_PMASK ((1 << (MEM_GRANULARITY_BITS - 3)) - 1) #define MEM_GRANULARITY_PMASK ((1 << (MEM_GRANULARITY_BITS - 3)) - 1)
#define MEM_MAPPINGS_NO ((0x100000 >> MEM_GRANULARITY_BITS) << 12) #define MEM_MAPPINGS_NO ((0x100000 >> MEM_GRANULARITY_BITS) << 12)
#define MEM_GRANULARITY_PAGE (MEM_GRANULARITY_MASK & ~0xfff) #define MEM_GRANULARITY_PAGE (MEM_GRANULARITY_MASK & ~0xfff)
#endif #define MEM_GRANULARITY_BASE (~MEM_GRANULARITY_MASK)
#define mem_set_mem_state_common(smm, base, size, state) mem_set_state(!!smm, 0, base, size, state) /* Compatibility #defines. */
#define mem_set_mem_state(base, size, state) mem_set_state(0, 0, base, size, state) #define mem_set_state(smm, mode, base, size, access) \
#define mem_set_mem_state_smm(base, size, state) mem_set_state(1, 0, base, size, state) mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), mode, base, size, access)
#define mem_set_mem_state_both(base, size, state) mem_set_state(2, 0, base, size, state) #define mem_set_mem_state_common(smm, base, size, access) \
#define mem_set_mem_state_smram(smm, base, size, is_smram) mem_set_state(!!smm, 1, base, size, is_smram) mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 0, base, size, access)
#define mem_set_mem_state_smram_ex(smm, base, size, is_smram) mem_set_state(!!smm, 2, base, size, is_smram) #define mem_set_mem_state(base, size, access) \
mem_set_access(ACCESS_NORMAL, 0, base, size, access)
#define mem_set_mem_state_smm(base, size, access) \
mem_set_access(ACCESS_SMM, 0, base, size, access)
#define mem_set_mem_state_both(base, size, access) \
mem_set_access(ACCESS_ALL, 0, base, size, access)
#define mem_set_mem_state_smram(smm, base, size, is_smram) \
mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 1, base, size, is_smram)
#define mem_set_mem_state_smram_ex(smm, base, size, is_smram) \
mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 2, base, size, is_smram)
#define flushmmucache_cr3 \
flushmmucache_nopc
typedef struct {
uint16_t x :5,
w :5,
r :5,
pad :1;
} state_t;
typedef union {
uint16_t vals[4];
state_t states[4];
} mem_state_t;
typedef struct _mem_mapping_ { typedef struct _mem_mapping_ {
struct _mem_mapping_ *prev, *next; struct _mem_mapping_ *prev, *next;
@@ -121,9 +171,9 @@ typedef struct _mem_mapping_ {
uint32_t flags; uint32_t flags;
void *p; /* backpointer to mapping or device */ /* There is never a needed to pass a pointer to the mapping itself, it is much preferable to
prepare a structure with the requires data (usually, the base address and mask) instead. */
void *dev; /* backpointer to memory device */ void *p; /* backpointer to device */
} mem_mapping_t; } mem_mapping_t;
#ifdef USE_NEW_DYNAREC #ifdef USE_NEW_DYNAREC
@@ -260,8 +310,18 @@ extern uint32_t mmutranslatereal32(uint32_t addr, int rw);
extern void addreadlookup(uint32_t virt, uint32_t phys); extern void addreadlookup(uint32_t virt, uint32_t phys);
extern void addwritelookup(uint32_t virt, uint32_t phys); extern void addwritelookup(uint32_t virt, uint32_t phys);
extern void mem_mapping_del(mem_mapping_t *); extern void mem_mapping_set(mem_mapping_t *,
uint32_t base,
uint32_t size,
uint8_t (*read_b)(uint32_t addr, void *p),
uint16_t (*read_w)(uint32_t addr, void *p),
uint32_t (*read_l)(uint32_t addr, void *p),
void (*write_b)(uint32_t addr, uint8_t val, void *p),
void (*write_w)(uint32_t addr, uint16_t val, void *p),
void (*write_l)(uint32_t addr, uint32_t val, void *p),
uint8_t *exec,
uint32_t flags,
void *p);
extern void mem_mapping_add(mem_mapping_t *, extern void mem_mapping_add(mem_mapping_t *,
uint32_t base, uint32_t base,
uint32_t size, uint32_t size,
@@ -285,8 +345,6 @@ extern void mem_mapping_set_handler(mem_mapping_t *,
extern void mem_mapping_set_p(mem_mapping_t *, void *p); extern void mem_mapping_set_p(mem_mapping_t *, void *p);
extern void mem_mapping_set_dev(mem_mapping_t *, void *dev);
extern void mem_mapping_set_addr(mem_mapping_t *, extern void mem_mapping_set_addr(mem_mapping_t *,
uint32_t base, uint32_t size); uint32_t base, uint32_t size);
extern void mem_mapping_set_exec(mem_mapping_t *, uint8_t *exec); extern void mem_mapping_set_exec(mem_mapping_t *, uint8_t *exec);
@@ -294,7 +352,7 @@ extern void mem_mapping_disable(mem_mapping_t *);
extern void mem_mapping_enable(mem_mapping_t *); extern void mem_mapping_enable(mem_mapping_t *);
extern void mem_mapping_recalc(uint64_t base, uint64_t size); extern void mem_mapping_recalc(uint64_t base, uint64_t size);
extern void mem_set_state(int smm, int mode, uint32_t base, uint32_t size, uint32_t state); extern void mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t access);
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);
@@ -333,7 +391,6 @@ extern void mem_flush_write_page(uint32_t addr, uint32_t virt);
extern void mem_reset_page_blocks(void); extern void mem_reset_page_blocks(void);
extern void flushmmucache(void); extern void flushmmucache(void);
extern void flushmmucache_cr3(void);
extern void flushmmucache_nopc(void); extern void flushmmucache_nopc(void);
extern void mmu_invalidate(uint32_t addr); extern void mmu_invalidate(uint32_t addr);

View File

@@ -67,6 +67,9 @@ extern int bios_load_linear_combined(char *fn1, char *fn2,
extern int bios_load_linear_combined2(char *fn1, char *fn2, extern int bios_load_linear_combined2(char *fn1, char *fn2,
char *fn3, char *fn4, char *fn5, char *fn3, char *fn4, char *fn5,
int sz, int off); int sz, int off);
extern int bios_load_linear_combined2_ex(char *fn1, char *fn2,
char *fn3, char *fn4, char *fn5,
int sz, int off);
extern int rom_init(rom_t *rom, char *fn, uint32_t address, int size, extern int rom_init(rom_t *rom, char *fn, uint32_t address, int size,
int mask, int file_offset, uint32_t flags); int mask, int file_offset, uint32_t flags);

View File

@@ -54,9 +54,7 @@
mem_mapping_t ram_low_mapping, /* 0..640K mapping */ mem_mapping_t ram_low_mapping, /* 0..640K mapping */
#if 1
ram_mid_mapping, ram_mid_mapping,
#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_2gb_mapping, /* 1024M+ mapping */
@@ -106,11 +104,13 @@ int mem_a20_key = 0,
int mmuflush = 0; int mmuflush = 0;
int mmu_perm = 4; int mmu_perm = 4;
#ifdef USE_NEW_DYNAREC
uint64_t *byte_dirty_mask; uint64_t *byte_dirty_mask;
uint64_t *byte_code_present_mask; uint64_t *byte_code_present_mask;
uint32_t purgable_page_list_head = 0; uint32_t purgable_page_list_head = 0;
int purgeable_page_count = 0; int purgeable_page_count = 0;
#endif
uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */ uint8_t high_page = 0; /* if a high (> 4 gb) page was detected */
@@ -122,9 +122,11 @@ static uint8_t *writelookupp;
static mem_mapping_t *base_mapping, *last_mapping; static mem_mapping_t *base_mapping, *last_mapping;
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 ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static mem_mapping_t *read_mapping_bus[MEM_MAPPINGS_NO];
static mem_mapping_t *write_mapping_bus[MEM_MAPPINGS_NO];
static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint8_t *_mem_exec[MEM_MAPPINGS_NO];
static uint32_t _mem_state[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
static mem_state_t _mem_state[MEM_MAPPINGS_NO];
static uint32_t remap_start_addr; static uint32_t remap_start_addr;
@@ -237,28 +239,6 @@ flushmmucache_nopc(void)
} }
void
flushmmucache_cr3(void)
{
int c;
for (c = 0; c < 256; c++) {
if (readlookup[c] != (int) 0xffffffff) {
readlookup2[readlookup[c]] = LOOKUP_INV;
readlookupp[readlookup[c]] = 4;
readlookup[c] = 0xffffffff;
}
if (writelookup[c] != (int) 0xffffffff) {
page_lookup[writelookup[c]] = NULL;
page_lookupp[writelookup[c]] = 4;
writelookup2[writelookup[c]] = LOOKUP_INV;
writelookupp[writelookup[c]] = 4;
writelookup[c] = 0xffffffff;
}
}
}
void void
mem_flush_write_page(uint32_t addr, uint32_t virt) mem_flush_write_page(uint32_t addr, uint32_t virt)
{ {
@@ -682,7 +662,7 @@ getpccache(uint32_t a)
if (_mem_exec[a64 >> MEM_GRANULARITY_BITS]) { if (_mem_exec[a64 >> MEM_GRANULARITY_BITS]) {
if (is286) { if (is286) {
if (read_mapping[a64 >> MEM_GRANULARITY_BITS] && (read_mapping[a64 >> MEM_GRANULARITY_BITS]->flags & MEM_MAPPING_ROM)) if (read_mapping[a64 >> MEM_GRANULARITY_BITS] && (read_mapping[a64 >> MEM_GRANULARITY_BITS]->flags & MEM_MAPPING_ROM_WS))
cpu_prefetch_cycles = cpu_rom_prefetch_cycles; cpu_prefetch_cycles = cpu_rom_prefetch_cycles;
else else
cpu_prefetch_cycles = cpu_mem_prefetch_cycles; cpu_prefetch_cycles = cpu_mem_prefetch_cycles;
@@ -1647,35 +1627,20 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write)
} }
int
mem_mapping_is_romcs(uint32_t addr, int write)
{
mem_mapping_t *map;
if (write)
map = write_mapping[addr >> MEM_GRANULARITY_BITS];
else
map = read_mapping[addr >> MEM_GRANULARITY_BITS];
if (map)
return !!(map->flags & MEM_MAPPING_ROMCS);
else
return 0;
}
uint8_t uint8_t
mem_readb_phys(uint32_t addr) mem_readb_phys(uint32_t addr)
{ {
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS];
uint8_t ret = 0xff; uint8_t ret = 0xff;
mem_logical_addr = 0xffffffff; mem_logical_addr = 0xffffffff;
if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) if (map) {
ret = _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]; if (map->exec)
else if (map && map->read_b) ret = map->exec[addr - map->base];
ret = map->read_b(addr, map->p); else if (map->read_b)
ret = map->read_b(addr, map->p);
}
return ret; return ret;
} }
@@ -1684,13 +1649,13 @@ mem_readb_phys(uint32_t addr)
uint16_t uint16_t
mem_readw_phys(uint32_t addr) mem_readw_phys(uint32_t addr)
{ {
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS];
uint16_t ret, *p; uint16_t ret, *p;
mem_logical_addr = 0xffffffff; mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) {
p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]); p = (uint16_t *) &(map->exec[addr - map->base]);
ret = *p; ret = *p;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w))
ret = map->read_w(addr, map->p); ret = map->read_w(addr, map->p);
@@ -1706,13 +1671,13 @@ mem_readw_phys(uint32_t addr)
uint32_t uint32_t
mem_readl_phys(uint32_t addr) mem_readl_phys(uint32_t addr)
{ {
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; mem_mapping_t *map = read_mapping_bus[addr >> MEM_GRANULARITY_BITS];
uint32_t ret, *p; uint32_t ret, *p;
mem_logical_addr = 0xffffffff; mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) {
p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]); p = (uint32_t *) &(map->exec[addr - map->base]);
ret = *p; ret = *p;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l))
ret = map->read_l(addr, map->p); ret = map->read_l(addr, map->p);
@@ -1748,28 +1713,29 @@ mem_read_phys(void *dest, uint32_t addr, int transfer_size)
void void
mem_writeb_phys(uint32_t addr, uint8_t val) mem_writeb_phys(uint32_t addr, uint8_t val)
{ {
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; mem_mapping_t *map = write_mapping_bus[addr >> MEM_GRANULARITY_BITS];
mem_logical_addr = 0xffffffff; mem_logical_addr = 0xffffffff;
if ((_mem_exec[addr >> MEM_GRANULARITY_BITS]) && (map && map->write_b)) if (map) {
_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val; if (map->exec)
else if (map && map->write_b) map->exec[addr - map->base] = val;
map->write_b(addr, val, map->p); else if (map->write_b)
map->write_b(addr, val, map->p);
}
} }
void void
mem_writew_phys(uint32_t addr, uint16_t val) mem_writew_phys(uint32_t addr, uint16_t val)
{ {
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; mem_mapping_t *map = write_mapping_bus[addr >> MEM_GRANULARITY_BITS];
uint16_t *p; uint16_t *p;
mem_logical_addr = 0xffffffff; mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS]) && if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) {
(map && map->write_w)) { p = (uint16_t *) &(map->exec[addr - map->base]);
p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
*p = val; *p = val;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w))
map->write_w(addr, val, map->p); map->write_w(addr, val, map->p);
@@ -1783,14 +1749,13 @@ mem_writew_phys(uint32_t addr, uint16_t val)
void void
mem_writel_phys(uint32_t addr, uint32_t val) mem_writel_phys(uint32_t addr, uint32_t val)
{ {
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; mem_mapping_t *map = write_mapping_bus[addr >> MEM_GRANULARITY_BITS];
uint32_t *p; uint32_t *p;
mem_logical_addr = 0xffffffff; mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS]) && if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) {
(map && map->write_l)) { p = (uint32_t *) &(map->exec[addr - map->base]);
p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
*p = val; *p = val;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l))
map->write_l(addr, val, map->p); map->write_l(addr, val, map->p);
@@ -2270,104 +2235,27 @@ mem_invalidate_range(uint32_t start_addr, uint32_t end_addr)
static __inline int static __inline int
mem_mapping_read_allowed(uint32_t flags, uint32_t state, int exec) mem_mapping_access_allowed(uint32_t flags, uint16_t access)
{ {
uint32_t smm_state = state >> MEM_STATE_SMM_SHIFT;
uint32_t state_masked;
int ret = 0; int ret = 0;
if (in_smm && ((smm_state & MEM_READ_MASK) != MEM_READ_NORMAL)) if (!(access & ACCESS_DISABLED)) {
state = smm_state; if (access & ACCESS_CACHE)
ret = (flags & MEM_MAPPING_CACHE);
else if (access & ACCESS_SMRAM)
ret = (flags & MEM_MAPPING_SMRAM);
else if (!(access & ACCESS_INTERNAL)) {
if (flags & MEM_MAPPING_IS_ROM) {
if (access & ACCESS_ROMCS)
ret = (flags & MEM_MAPPING_ROMCS);
else
ret = !(flags & MEM_MAPPING_ROMCS);
} else
ret = 1;
state_masked = (state & MEM_READ_MASK); ret = ret && !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
} else
if (state_masked & MEM_READ_SMRAM)
ret = (flags & MEM_MAPPING_SMRAM);
else if ((state_masked & MEM_READ_SMRAM_EX) && exec)
ret = (flags & MEM_MAPPING_SMRAM);
else if (!(state_masked & MEM_READ_DISABLED_EX)) switch (state_masked) {
case MEM_READ_ANY:
ret = !(flags & MEM_MAPPING_SMRAM);
break;
/* On external and 0 mappings without ROMCS. */
case MEM_READ_EXTERNAL:
ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM);
break;
/* On external and 0 mappings with ROMCS. */
case MEM_READ_ROMCS:
ret = !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM);
break;
/* On any external mappings. */
case MEM_READ_EXTANY:
ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
break;
case MEM_READ_EXTERNAL_EX:
if (exec)
ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM);
else
ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
break;
case MEM_READ_INTERNAL:
ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM); ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM);
break;
default:
if (state_masked != MEM_READ_DISABLED)
fatal("mem_mapping_read_allowed : bad state %x\n", state_masked);
break;
}
return ret;
}
static __inline int
mem_mapping_write_allowed(uint32_t flags, uint32_t state)
{
uint32_t smm_state = state >> MEM_STATE_SMM_SHIFT;
uint32_t state_masked;
int ret = 0;
if (in_smm && ((smm_state & MEM_WRITE_MASK) != MEM_WRITE_NORMAL))
state = smm_state;
state_masked = (state & MEM_WRITE_MASK);
if (state_masked & MEM_WRITE_SMRAM)
ret = (flags & MEM_MAPPING_SMRAM);
else if (!(state_masked & MEM_WRITE_DISABLED_EX)) switch (state_masked) {
case MEM_WRITE_ANY:
ret = !(flags & MEM_MAPPING_SMRAM);
break;
/* On external and 0 mappings without ROMCS. */
case MEM_WRITE_EXTERNAL:
ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM);
break;
/* On external and 0 mappings with ROMCS. */
case MEM_WRITE_ROMCS:
ret = !(flags & MEM_MAPPING_INTERNAL) && (flags & MEM_MAPPING_ROMCS) && !(flags & MEM_MAPPING_SMRAM);
break;
/* On any external mappings. */
case MEM_WRITE_EXTANY:
ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
break;
case MEM_WRITE_INTERNAL:
ret = !(flags & MEM_MAPPING_EXTERNAL) && !(flags & MEM_MAPPING_SMRAM);
break;
default:
if (state_masked != MEM_WRITE_DISABLED)
fatal("mem_mapping_write_allowed : bad state %x\n", state_masked);
break;
} }
return ret; return ret;
@@ -2378,6 +2266,7 @@ void
mem_mapping_recalc(uint64_t base, uint64_t size) mem_mapping_recalc(uint64_t base, uint64_t size)
{ {
mem_mapping_t *map; mem_mapping_t *map;
int n;
uint64_t c; uint64_t c;
if (!size || (base_mapping == NULL)) if (!size || (base_mapping == NULL))
@@ -2387,46 +2276,45 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
/* Clear out old mappings. */ /* Clear out old mappings. */
for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) { for (c = base; c < base + size; c += MEM_GRANULARITY_SIZE) {
read_mapping[c >> MEM_GRANULARITY_BITS] = NULL;
write_mapping[c >> MEM_GRANULARITY_BITS] = NULL;
_mem_exec[c >> MEM_GRANULARITY_BITS] = NULL; _mem_exec[c >> MEM_GRANULARITY_BITS] = NULL;
write_mapping[c >> MEM_GRANULARITY_BITS] = NULL;
read_mapping[c >> MEM_GRANULARITY_BITS] = NULL;
write_mapping_bus[c >> MEM_GRANULARITY_BITS] = NULL;
read_mapping_bus[c >> MEM_GRANULARITY_BITS] = NULL;
} }
/* Walk mapping list. */ /* Walk mapping list. */
while (map != NULL) { while (map != NULL) {
/*In range?*/ /* In range? */
mem_log("mem_mapping_recalc(): %08X -> %08X\n", map, map->next); if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) &&
if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) { ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) {
uint64_t start = (map->base < base) ? map->base : base; uint64_t start = (map->base < base) ? map->base : base;
uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ? ((uint64_t)map->base + (uint64_t)map->size) : (base + size); uint64_t end = (((uint64_t)map->base + (uint64_t)map->size) < (base + size)) ?
((uint64_t)map->base + (uint64_t)map->size) : (base + size);
if (start < map->base) if (start < map->base)
start = map->base; start = map->base;
for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { for (c = start; c < end; c += MEM_GRANULARITY_SIZE) {
if ((map->read_b || map->read_w || map->read_l) && /* CPU */
mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS], 0)) { n = !!in_smm;
#ifdef ENABLE_MEM_LOG
if ((start >= 0xa0000) && (start <= 0xbffff))
mem_log("Read allowed: %08X (mapping for %08X)\n", map, start);
#endif
read_mapping[c >> MEM_GRANULARITY_BITS] = map;
}
if (map->exec && if (map->exec &&
mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS], 1)) { mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x))
#ifdef ENABLE_MEM_LOG
if ((start >= 0xa0000) && (start <= 0xbffff))
mem_log("Exec allowed: %08X (mapping for %08X)\n", map, start);
#endif
_mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base);
}
if ((map->write_b || map->write_w || map->write_l) && if ((map->write_b || map->write_w || map->write_l) &&
mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) { mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w))
#ifdef ENABLE_MEM_LOG
if ((start >= 0xa0000) && (start <= 0xbffff))
mem_log("Write allowed: %08X (mapping for %08X)\n", map, start);
#endif
write_mapping[c >> MEM_GRANULARITY_BITS] = map; write_mapping[c >> MEM_GRANULARITY_BITS] = map;
} if ((map->read_b || map->read_w || map->read_l) &&
mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r))
read_mapping[c >> MEM_GRANULARITY_BITS] = map;
/* Bus */
n |= STATE_BUS;
if ((map->write_b || map->write_w || map->write_l) &&
mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w))
write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map;
if ((map->read_b || map->read_w || map->read_l) &&
mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r))
read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map;
} }
} }
map = map->next; map = map->next;
@@ -2437,37 +2325,40 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
void void
mem_mapping_del(mem_mapping_t *map) mem_mapping_set(mem_mapping_t *map,
uint32_t base,
uint32_t size,
uint8_t (*read_b)(uint32_t addr, void *p),
uint16_t (*read_w)(uint32_t addr, void *p),
uint32_t (*read_l)(uint32_t addr, void *p),
void (*write_b)(uint32_t addr, uint8_t val, void *p),
void (*write_w)(uint32_t addr, uint16_t val, void *p),
void (*write_l)(uint32_t addr, uint32_t val, void *p),
uint8_t *exec,
uint32_t fl,
void *p)
{ {
/* Do a sanity check */ if (size != 0x00000000)
if ((base_mapping == NULL) && (last_mapping != NULL)) { map->enable = 1;
fatal("mem_mapping_del(): NULL base mapping with non-NULL last mapping\n"); else
return; map->enable = 0;
} else if ((base_mapping != NULL) && (last_mapping == NULL)) { map->base = base;
fatal("mem_mapping_del(): Non-NULL base mapping with NULL last mapping\n"); map->size = size;
return; map->read_b = read_b;
} else if ((base_mapping != NULL) && (base_mapping->prev != NULL)) { map->read_w = read_w;
fatal("mem_mapping_del(): Base mapping with a preceding mapping\n"); map->read_l = read_l;
return; map->write_b = write_b;
} else if ((last_mapping != NULL) && (last_mapping->next != NULL)) { map->write_w = write_w;
fatal("mem_mapping_del(): Last mapping with a following mapping\n"); map->write_l = write_l;
return; map->exec = exec;
} map->flags = fl;
map->p = p;
map->next = NULL;
mem_log("mem_mapping_add(): Linked list structure: %08X -> %08X -> %08X\n", map->prev, map, map->next);
/* Disable the entry. */ /* If the mapping is disabled, there is no need to recalc anything. */
mem_mapping_disable(map); if (size != 0x00000000)
mem_mapping_recalc(map->base, map->size);
/* Zap it from the list. */
if (map->prev != NULL)
map->prev->next = map->next;
if (map->next != NULL)
map->next->prev = map->prev;
/* Check if it's the first or the last mapping. */
if (base_mapping == map)
base_mapping = map->next;
if (last_mapping == map)
last_mapping = map->prev;
} }
@@ -2513,28 +2404,8 @@ mem_mapping_add(mem_mapping_t *map,
} }
last_mapping = map; last_mapping = map;
if (size != 0x00000000) mem_mapping_set(map, base, size, read_b, read_w, read_l,
map->enable = 1; write_b, write_w, write_l, exec, fl, p);
else
map->enable = 0;
map->base = base;
map->size = size;
map->read_b = read_b;
map->read_w = read_w;
map->read_l = read_l;
map->write_b = write_b;
map->write_w = write_w;
map->write_l = write_l;
map->exec = exec;
map->flags = fl;
map->p = p;
map->dev = NULL;
map->next = NULL;
mem_log("mem_mapping_add(): Linked list structure: %08X -> %08X -> %08X\n", map->prev, map, map->next);
/* If the mapping is disabled, there is no need to recalc anything. */
if (size != 0x00000000)
mem_mapping_recalc(map->base, map->size);
} }
@@ -2597,13 +2468,6 @@ mem_mapping_set_p(mem_mapping_t *map, void *p)
} }
void
mem_mapping_set_dev(mem_mapping_t *map, void *p)
{
map->dev = p;
}
void void
mem_mapping_disable(mem_mapping_t *map) mem_mapping_disable(mem_mapping_t *map)
{ {
@@ -2623,47 +2487,40 @@ mem_mapping_enable(mem_mapping_t *map)
void void
mem_set_state(int smm, int mode, uint32_t base, uint32_t size, uint32_t state) mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t access)
{ {
uint32_t c, mask_l, mask_h, smstate = 0x0000; uint32_t c;
uint16_t mask, smstate = 0x0000;
const uint16_t smstates[4] = { 0x0000, (MEM_READ_SMRAM | MEM_WRITE_SMRAM),
MEM_READ_SMRAM_EX, (MEM_READ_DISABLED_EX | MEM_WRITE_DISABLED_EX) };
int i;
if (mode) { if (mode)
mask_l = 0xffff0f0f; mask = 0x2d6b;
mask_h = 0x0f0fffff; else
} else { mask = 0x1084;
mask_l = 0xfffff0f0;
mask_h = 0xf0f0ffff;
}
if (mode) { if (mode) {
if (mode == 1) if (mode == 1)
state = !!state; access = !!access;
switch (state & 0x03) { smstate = smstates[access & 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;
}
} else } else
smstate = state & 0x0f0f; smstate = access & 0x6f7b;
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) { for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
if (smm != 0) for (i = 0; i < 4; i++) {
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & mask_h) | (smstate << MEM_STATE_SMM_SHIFT); if (bitmap & (1 << i)) {
if (smm != 1) _mem_state[(c + base) >> MEM_GRANULARITY_BITS].vals[i] =
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & mask_l) | smstate; (_mem_state[(c + base) >> MEM_GRANULARITY_BITS].vals[i] & mask) | smstate;
}
}
#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, smstate); mem_log("Set mem state for block at %08X to %04X with bitmap %02X\n",
c + base, smstate, bitmap);
}
#endif #endif
} }
@@ -2694,7 +2551,7 @@ mem_close(void)
while (map != NULL) { while (map != NULL) {
next = map->next; next = map->next;
mem_mapping_del(map); map->prev = map->next = NULL;
map = next; map = next;
} }
@@ -2702,11 +2559,29 @@ mem_close(void)
} }
static void
mem_add_ram_mapping(mem_mapping_t *mapping, uint32_t base, uint32_t size)
{
mem_mapping_add(mapping, base, size,
mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml,
ram + base, MEM_MAPPING_INTERNAL, NULL);
}
static void
mem_init_ram_mapping(mem_mapping_t *mapping, uint32_t base, uint32_t size)
{
mem_set_mem_state_both(base, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_add_ram_mapping(mapping, base, size);
}
/* Reset the memory state. */ /* Reset the memory state. */
void void
mem_reset(void) mem_reset(void)
{ {
uint32_t c, m, m2; uint32_t c, m;
memset(page_ff, 0xff, sizeof(page_ff)); memset(page_ff, 0xff, sizeof(page_ff));
@@ -2778,14 +2653,6 @@ mem_reset(void)
m = 256; m = 256;
} }
/* Calculate the amount of pages used by RAM, so that we can
give all the pages above this amount NULL write handlers. */
m2 = (mem_size + 384) >> 2;
if ((m2 << 2) < (mem_size + 384))
m2++;
if (m2 < 4096)
m2 = 4096;
/* /*
* Allocate and initialize the (new) page table. * Allocate and initialize the (new) page table.
* We only do this if the size of the page table has changed. * We only do this if the size of the page table has changed.
@@ -2836,12 +2703,6 @@ mem_reset(void)
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;
pages[c].write_l = mem_write_raml_page; pages[c].write_l = mem_write_raml_page;
} else {
/* Make absolute sure non-RAM pages have NULL handlers so the
memory read/write handlers know to ignore them. */
pages[c].write_b = NULL;
pages[c].write_w = NULL;
pages[c].write_l = NULL;
} }
#ifdef USE_NEW_DYNAREC #ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST; pages[c].evict_prev = EVICT_NOT_IN_LIST;
@@ -2850,44 +2711,27 @@ mem_reset(void)
#endif #endif
} }
memset(read_mapping, 0x00, sizeof(read_mapping)); memset(_mem_exec, 0x00, sizeof(_mem_exec));
memset(write_mapping, 0x00, sizeof(write_mapping)); memset(write_mapping, 0x00, sizeof(write_mapping));
memset(read_mapping, 0x00, sizeof(read_mapping));
memset(_mem_exec, 0x00, sizeof(_mem_exec)); memset(write_mapping_bus, 0x00, sizeof(write_mapping_bus));
memset(read_mapping_bus, 0x00, sizeof(read_mapping_bus));
base_mapping = last_mapping = NULL; base_mapping = last_mapping = NULL;
/* Set the entire memory space as external. */ /* Set the entire memory space as external. */
memset(_mem_state, 0x02, sizeof(_mem_state)); memset(_mem_state, 0x00, sizeof(_mem_state));
/* Set the low RAM space as internal. */ /* Set the low RAM space as internal. */
mem_set_mem_state_both(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_init_ram_mapping(&ram_low_mapping, 0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024);
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_mapping_add(&ram_low_mapping, 0x00000,
(mem_size > 640) ? 0xa0000 : mem_size * 1024,
mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml,
ram, MEM_MAPPING_INTERNAL, NULL);
if (mem_size > 1024) { if (mem_size > 1024) {
if (cpu_16bitbus && mem_size > 16256) { if (cpu_16bitbus && mem_size > 16256)
mem_set_mem_state_both(0x100000, (16256 - 1024) * 1024, mem_init_ram_mapping(&ram_high_mapping, 0x100000, (16256 - 1024) * 1024);
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); else {
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 {
if (mem_size > 1048576) { if (mem_size > 1048576) {
mem_set_mem_state_both(0x100000, (1048576 - 1024) * 1024, mem_init_ram_mapping(&ram_high_mapping, 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_set_mem_state_both((1 << 30), (mem_size - 1048576) * 1024,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_mapping_add(&ram_2gb_mapping, (1 << 30), mem_mapping_add(&ram_2gb_mapping, (1 << 30),
@@ -2895,24 +2739,13 @@ mem_reset(void)
mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl, mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl,
mem_write_ram,mem_write_ramw,mem_write_raml, mem_write_ram,mem_write_ramw,mem_write_raml,
ram2, MEM_MAPPING_INTERNAL, NULL); ram2, MEM_MAPPING_INTERNAL, NULL);
} else { } else
mem_set_mem_state_both(0x100000, (mem_size - 1024) * 1024, mem_init_ram_mapping(&ram_high_mapping, 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 > 768) { if (mem_size > 768)
mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_add_ram_mapping(&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_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,
@@ -2953,16 +2786,17 @@ mem_remap_top(int kb)
uint32_t 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;
int set = 1;
static int old_kb = 0;
mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size);
if (mem_size <= 640) return; if (mem_size <= 640) return;
if (kb == 0) { if (kb == 0) {
/* Called to disable the mapping. */ kb = old_kb;
mem_mapping_disable(&ram_remapped_mapping); set = 0;
} else
return; old_kb = kb;
}
if (size > kb) if (size > kb)
size = kb; size = kb;
@@ -2971,10 +2805,10 @@ mem_remap_top(int kb)
for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) {
offset = c - ((start * 1024) >> 12); offset = c - ((start * 1024) >> 12);
pages[c].mem = &ram[0xA0000 + (offset << 12)]; pages[c].mem = set ? &ram[0xa0000 + (offset << 12)] : page_ff;
pages[c].write_b = mem_write_ramb_page; pages[c].write_b = set ? mem_write_ramb_page : NULL;
pages[c].write_w = mem_write_ramw_page; pages[c].write_w = set ? mem_write_ramw_page : NULL;
pages[c].write_l = mem_write_raml_page; pages[c].write_l = set ? mem_write_raml_page : NULL;
#ifdef USE_NEW_DYNAREC #ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST; pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64];
@@ -2982,10 +2816,14 @@ mem_remap_top(int kb)
#endif #endif
} }
mem_set_mem_state_both(start * 1024, size * 1024, mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
mem_mapping_set_exec(&ram_remapped_mapping, ram + 0xa0000); if (set) {
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
mem_mapping_set_exec(&ram_remapped_mapping, ram + 0xa0000);
} else
mem_mapping_disable(&ram_remapped_mapping);
flushmmucache(); flushmmucache();
} }

View File

@@ -506,6 +506,22 @@ bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5
} }
int
bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off)
{
uint8_t ret = 0;
ret = bios_load_linear(fn3, 0x000e0000, 262144, off);
ret &= bios_load_aux_linear(fn1, 0x000c0000, 65536, off);
ret &= bios_load_aux_linear(fn2, 0x000d0000, 65536, off);
ret &= bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off);
if (fn5 != NULL)
ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0);
return ret;
}
int int
rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags)
{ {
@@ -530,7 +546,7 @@ rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_
addr, sz, addr, sz,
rom_read, rom_readw, rom_readl, rom_read, rom_readw, rom_readl,
NULL, NULL, NULL, NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM, rom); rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0); return(0);
} }