Rewrote memory access handling to properly split execute from read, bus from CPU (but the mappings will still match until otherwise specified), and fixed exec[] usage by the mem_*_phys() functions.

This commit is contained in:
OBattler
2021-04-22 04:27:50 +02:00
parent b0870d5055
commit 957b538c4a
10 changed files with 445 additions and 550 deletions

View File

@@ -723,6 +723,8 @@ pc_reset_hard_close(void)
closeal();
video_reset_close();
cpu_close();
}

View File

@@ -250,16 +250,11 @@ neat_log(const char *fmt, ...)
static uint8_t
ems_readb(uint32_t addr, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
neat_t *dev = (neat_t *)map->dev;
neat_t *dev = (neat_t *)priv;
uint8_t ret = 0xff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* 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);
}
@@ -268,16 +263,11 @@ ems_readb(uint32_t addr, void *priv)
static uint16_t
ems_readw(uint32_t addr, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
neat_t *dev = (neat_t *)map->dev;
neat_t *dev = (neat_t *)priv;
uint16_t ret = 0xffff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* 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);
}
@@ -286,30 +276,20 @@ ems_readw(uint32_t addr, void *priv)
static void
ems_writeb(uint32_t addr, uint8_t val, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
neat_t *dev = (neat_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
neat_t *dev = (neat_t *)priv;
/* 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. */
static void
ems_writew(uint32_t addr, uint16_t val, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
neat_t *dev = (neat_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
neat_t *dev = (neat_t *)priv;
/* 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. */
@@ -436,8 +416,7 @@ ems_init(neat_t *dev, int en)
ems_readb, ems_readw, NULL,
ems_writeb, ems_writew, NULL,
ram, MEM_MAPPING_EXTERNAL,
&dev->ems[i].mapping);
mem_mapping_set_dev(&dev->ems[i].mapping, dev);
dev);
/* Disable for now. */
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 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_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
cpu_set(void)
{
cpu_inited = 1;
cpu_effective = cpu;
cpu_s = (CPU *) &cpu_f->cpus[cpu_effective];
@@ -1365,6 +1367,13 @@ cpu_set(void)
}
void
cpu_close(void)
{
cpu_inited = 0;
}
void
cpu_set_isa_speed(int speed)
{

View File

@@ -511,7 +511,7 @@ extern int cgate16;
extern int cpl_override;
extern int CPUID;
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 pccache;
extern uint8_t *pccache2;
@@ -606,6 +606,7 @@ extern char *cpu_current_pc(char *bufp);
extern void cpu_update_waitstates(void);
extern void cpu_set(void);
extern void cpu_close(void);
extern void cpu_set_isa_speed(int speed);
extern void cpu_set_pci_speed(int speed);
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_high = 0xffff;
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->seg = AT ? 0xf000 : 0xffff;
} else {

View File

@@ -103,6 +103,11 @@ typedef struct {
mem_mapping_t mapping; /* mapping entry for page */
} emsreg_t;
typedef struct {
uint32_t base;
uint8_t *ptr;
} ext_ram_t;
typedef struct {
const char *name;
uint8_t board : 6, /* board type */
@@ -125,6 +130,8 @@ typedef struct {
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 high_mapping; /* mapping for high mem */
@@ -151,16 +158,17 @@ isamem_log(const char *fmt, ...)
#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. */
static uint8_t
ram_readb(uint32_t addr, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
ext_ram_t *dev = (ext_ram_t *)priv;
uint8_t ret = 0xff;
/* Grab the data. */
ret = *(uint8_t *)(dev->ram + (addr - map->base));
ret = *(uint8_t *)(dev->ptr + (addr - dev->base));
return(ret);
}
@@ -170,12 +178,11 @@ ram_readb(uint32_t addr, void *priv)
static uint16_t
ram_readw(uint32_t addr, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
ext_ram_t *dev = (ext_ram_t *)priv;
uint16_t ret = 0xffff;
/* Grab the data. */
ret = *(uint16_t *)(dev->ram + (addr - map->base));
ret = *(uint16_t *)(dev->ptr + (addr - dev->base));
return(ret);
}
@@ -185,11 +192,10 @@ ram_readw(uint32_t addr, void *priv)
static void
ram_writeb(uint32_t addr, uint8_t val, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
ext_ram_t *dev = (ext_ram_t *)priv;
/* 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
ram_writew(uint32_t addr, uint16_t val, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
ext_ram_t *dev = (ext_ram_t *)priv;
/* 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
ems_readb(uint32_t addr, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
memdev_t *dev = (memdev_t *)priv;
uint8_t ret = 0xff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* 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 ((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
return(ret);
@@ -231,18 +231,13 @@ ems_readb(uint32_t addr, void *priv)
static uint16_t
ems_readw(uint32_t addr, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
memdev_t *dev = (memdev_t *)priv;
uint16_t ret = 0xffff;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
/* 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 ((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
return(ret);
@@ -253,18 +248,13 @@ ems_readw(uint32_t addr, void *priv)
static void
ems_writeb(uint32_t addr, uint8_t val, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
memdev_t *dev = (memdev_t *)priv;
/* Write the data. */
#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
*(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
ems_writew(uint32_t addr, uint16_t val, void *priv)
{
mem_mapping_t *map = (mem_mapping_t *)priv;
memdev_t *dev = (memdev_t *)map->dev;
int vpage;
/* Get the viewport page number. */
vpage = ((addr & 0xffff) / EMS_PGSIZE);
memdev_t *dev = (memdev_t *)priv;
/* Write the data. */
#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
*(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;
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. */
mem_mapping_add(&dev->low_mapping, addr, t,
ram_readb,
@@ -517,8 +505,7 @@ dev->frame_addr = 0xE0000;
ram_writeb,
(dev->flags&FLAG_WIDE) ? ram_writew : NULL,
NULL,
ptr, MEM_MAPPING_EXTERNAL, &dev->low_mapping);
mem_mapping_set_dev(&dev->low_mapping, dev);
ptr, MEM_MAPPING_EXTERNAL, &dev->ext_ram[0]);
/* Tell the memory system this is external RAM. */
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);
dev->ext_ram[1].ptr = ptr;
dev->ext_ram[1].base = addr + tot;
/* Update and enable the remap. */
mem_mapping_del(&ram_remapped_mapping);
mem_mapping_add(&ram_remapped_mapping,
mem_mapping_set(&ram_remapped_mapping,
addr + tot, t,
ram_readb, ram_readw, NULL,
ram_writeb, ram_writew, NULL,
ptr, MEM_MAPPING_EXTERNAL,
&ram_remapped_mapping);
mem_mapping_set_exec(&ram_remapped_mapping, ptr);
mem_mapping_set_dev(&ram_remapped_mapping, dev);
&dev->ext_ram[1]);
mem_mapping_disable(&ram_remapped_mapping);
/* Tell the memory system this is external RAM. */
@@ -576,12 +563,14 @@ dev->frame_addr = 0xE0000;
t = tot;
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. */
mem_mapping_add(&dev->high_mapping, addr, t,
ram_readb, ram_readw, NULL,
ram_writeb, ram_writew, NULL,
ptr, MEM_MAPPING_EXTERNAL, &dev->high_mapping);
mem_mapping_set_dev(&dev->high_mapping, dev);
ptr, MEM_MAPPING_EXTERNAL, &dev->ext_ram[2]);
/* Tell the memory system this is external RAM. */
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,
NULL,
ptr, MEM_MAPPING_EXTERNAL,
&dev->ems[i].mapping);
mem_mapping_set_dev(&dev->ems[i].mapping, dev);
dev);
/* For now, disable it. */
mem_mapping_disable(&dev->ems[i].mapping);

View File

@@ -22,66 +22,93 @@
# 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_RAM_ADDR_MASK 2
/* _mem_state layout:
Bits 0 - 7: Normal write
Bits 8 -15: Normal read
Bits 16 -23: SMM write
Bits 24 -31: SMM read
*/
#define STATE_CPU 0
#define STATE_BUS 2
#define MEM_READ_DISABLED 0x0000
#define MEM_READ_INTERNAL 0x0100
#define MEM_READ_EXTERNAL 0x0200
#define MEM_READ_ANY 0x0300
#define MEM_READ_NORMAL 0x0400 /* SMM only - means use the non-SMM state */
#define MEM_READ_EXTERNAL_EX 0x0500 /* External but with internal exec - needed by the VIA Apollo Pro */
#define MEM_READ_ROMCS 0x0600 /* EXTERNAL type + ROMC flag */
#define MEM_READ_EXTANY 0x0700 /* Any EXTERNAL type */
#define MEM_READ_SMRAM 0x1000
#define MEM_READ_SMRAM_EX 0x2000
#define MEM_READ_DISABLED_EX 0x4000
#define MEM_READ_MASK 0xff00
#define ACCESS_CPU 1 /* Update CPU non-SMM access. */
#define ACCESS_CPU_SMM 2 /* Update CPU SMM access. */
#define ACCESS_BUS 4 /* Update bus access. */
#define ACCESS_BUS_SMM 8 /* Update bus SMM access. */
#define ACCESS_NORMAL 5 /* Update CPU and bus non-SMM accesses. */
#define ACCESS_SMM 10 /* Update CPU and bus SMM accesses. */
#define ACCESS_CPU_BOTH 3 /* Update CPU non-SMM and SMM accesses. */
#define ACCESS_BUS_BOTH 12 /* Update bus non-SMM and SMM accesses. */
#define ACCESS_ALL 15 /* Update all accesses. */
#define MEM_WRITE_DISABLED 0x0000
#define MEM_WRITE_INTERNAL 0x0001
#define MEM_WRITE_EXTERNAL 0x0002
#define MEM_WRITE_ANY 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 ACCESS_INTERNAL 1
#define ACCESS_ROMCS 2
#define ACCESS_SMRAM 4
#define ACCESS_CACHE 8
#define ACCESS_DISABLED 16
#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
change in the future - 4k works, less does not because of
internal 4k pages. */
#ifdef DEFAULT_GRANULARITY
#define MEM_GRANULARITY_BITS 14
#define MEM_GRANULARITY_SIZE (1 << MEM_GRANULARITY_BITS)
#define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2)
#define MEM_GRANULARITY_QBOUND (MEM_GRANULARITY_SIZE - 4)
#define MEM_GRANULARITY_MASK (MEM_GRANULARITY_SIZE - 1)
#define MEM_GRANULARITY_HMASK ((1 << (MEM_GRANULARITY_BITS - 1)) - 1)
#define MEM_GRANULARITY_QMASK ((1 << (MEM_GRANULARITY_BITS - 2)) - 1)
#define MEM_GRANULARITY_PMASK ((1 << (MEM_GRANULARITY_BITS - 3)) - 1)
#define MEM_MAPPINGS_NO ((0x100000 >> MEM_GRANULARITY_BITS) << 12)
#define MEM_GRANULARITY_PAGE (MEM_GRANULARITY_MASK & ~0xfff)
#else
#define ACCESS_EXECUTE 0
#define ACCESS_READ 1
#define ACCESS_WRITE 2
/* Conversion #define's - we need these to seamlessly convert the old mem_set_mem_state() calls to
the new stuff in order to make this a drop in replacement.
Read here includes execute access since the old code also used read access for execute access,
with some exceptions. */
#define MEM_READ_DISABLED (ACCESS_X_DISABLED | ACCESS_R_DISABLED)
#define MEM_READ_INTERNAL (ACCESS_X_INTERNAL | ACCESS_R_INTERNAL)
#define MEM_READ_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_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_SIZE (1 << MEM_GRANULARITY_BITS)
#define MEM_GRANULARITY_HBOUND (MEM_GRANULARITY_SIZE - 2)
@@ -92,16 +119,39 @@
#define MEM_GRANULARITY_PMASK ((1 << (MEM_GRANULARITY_BITS - 3)) - 1)
#define MEM_MAPPINGS_NO ((0x100000 >> MEM_GRANULARITY_BITS) << 12)
#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)
#define mem_set_mem_state(base, size, state) mem_set_state(0, 0, base, size, state)
#define mem_set_mem_state_smm(base, size, state) mem_set_state(1, 0, base, size, state)
#define mem_set_mem_state_both(base, size, state) mem_set_state(2, 0, base, size, state)
#define mem_set_mem_state_smram(smm, base, size, is_smram) mem_set_state(!!smm, 1, base, size, is_smram)
#define mem_set_mem_state_smram_ex(smm, base, size, is_smram) mem_set_state(!!smm, 2, base, size, is_smram)
/* Compatibility #defines. */
#define mem_set_state(smm, mode, base, size, access) \
mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), mode, base, size, access)
#define mem_set_mem_state_common(smm, base, size, access) \
mem_set_access((smm ? ACCESS_SMM : ACCESS_NORMAL), 0, base, size, access)
#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_ {
struct _mem_mapping_ *prev, *next;
@@ -121,9 +171,9 @@ typedef struct _mem_mapping_ {
uint32_t flags;
void *p; /* backpointer to mapping or device */
void *dev; /* backpointer to memory 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 *p; /* backpointer to device */
} mem_mapping_t;
#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 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 *,
uint32_t base,
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_dev(mem_mapping_t *, void *dev);
extern void mem_mapping_set_addr(mem_mapping_t *,
uint32_t base, uint32_t size);
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_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 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 flushmmucache(void);
extern void flushmmucache_cr3(void);
extern void flushmmucache_nopc(void);
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,
char *fn3, char *fn4, char *fn5,
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,
int mask, int file_offset, uint32_t flags);

View File

@@ -54,9 +54,7 @@
mem_mapping_t ram_low_mapping, /* 0..640K mapping */
#if 1
ram_mid_mapping,
#endif
ram_remapped_mapping, /* 640..1024K mapping */
ram_high_mapping, /* 1024K+ mapping */
ram_2gb_mapping, /* 1024M+ mapping */
@@ -106,11 +104,13 @@ int mem_a20_key = 0,
int mmuflush = 0;
int mmu_perm = 4;
#ifdef USE_NEW_DYNAREC
uint64_t *byte_dirty_mask;
uint64_t *byte_code_present_mask;
uint32_t purgable_page_list_head = 0;
int purgeable_page_count = 0;
#endif
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 *read_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 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;
@@ -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
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 (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;
else
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
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;
mem_logical_addr = 0xffffffff;
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
ret = _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK];
else if (map && map->read_b)
if (map) {
if (map->exec)
ret = map->exec[addr - map->base];
else if (map->read_b)
ret = map->read_b(addr, map->p);
}
return ret;
}
@@ -1684,13 +1649,13 @@ mem_readb_phys(uint32_t addr)
uint16_t
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;
mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) {
p = (uint16_t *) &(map->exec[addr - map->base]);
ret = *p;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w))
ret = map->read_w(addr, map->p);
@@ -1706,13 +1671,13 @@ mem_readw_phys(uint32_t addr)
uint32_t
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;
mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) {
p = (uint32_t *) &(map->exec[addr - map->base]);
ret = *p;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l))
ret = map->read_l(addr, map->p);
@@ -1748,28 +1713,29 @@ mem_read_phys(void *dest, uint32_t addr, int transfer_size)
void
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;
if ((_mem_exec[addr >> MEM_GRANULARITY_BITS]) && (map && map->write_b))
_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val;
else if (map && map->write_b)
if (map) {
if (map->exec)
map->exec[addr - map->base] = val;
else if (map->write_b)
map->write_b(addr, val, map->p);
}
}
void
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;
mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS]) &&
(map && map->write_w)) {
p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->exec)) {
p = (uint16_t *) &(map->exec[addr - map->base]);
*p = val;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w))
map->write_w(addr, val, map->p);
@@ -1783,14 +1749,13 @@ mem_writew_phys(uint32_t addr, uint16_t val)
void
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;
mem_logical_addr = 0xffffffff;
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS]) &&
(map && map->write_l)) {
p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->exec)) {
p = (uint32_t *) &(map->exec[addr - map->base]);
*p = val;
} else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l))
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
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;
if (in_smm && ((smm_state & MEM_READ_MASK) != MEM_READ_NORMAL))
state = smm_state;
state_masked = (state & MEM_READ_MASK);
if (state_masked & MEM_READ_SMRAM)
if (!(access & ACCESS_DISABLED)) {
if (access & ACCESS_CACHE)
ret = (flags & MEM_MAPPING_CACHE);
else if (access & ACCESS_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 if (!(access & ACCESS_INTERNAL)) {
if (flags & MEM_MAPPING_IS_ROM) {
if (access & ACCESS_ROMCS)
ret = (flags & MEM_MAPPING_ROMCS);
else
ret = !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
break;
ret = !(flags & MEM_MAPPING_ROMCS);
} else
ret = 1;
case MEM_READ_INTERNAL:
ret = ret && !(flags & MEM_MAPPING_INTERNAL) && !(flags & MEM_MAPPING_SMRAM);
} else
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;
@@ -2378,6 +2266,7 @@ void
mem_mapping_recalc(uint64_t base, uint64_t size)
{
mem_mapping_t *map;
int n;
uint64_t c;
if (!size || (base_mapping == NULL))
@@ -2387,46 +2276,45 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
/* Clear out old mappings. */
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;
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. */
while (map != NULL) {
/* 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) && ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) {
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 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)
start = map->base;
for (c = start; c < end; c += MEM_GRANULARITY_SIZE) {
if ((map->read_b || map->read_w || map->read_l) &&
mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS], 0)) {
#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;
}
/* CPU */
n = !!in_smm;
if (map->exec &&
mem_mapping_read_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS], 1)) {
#ifdef ENABLE_MEM_LOG
if ((start >= 0xa0000) && (start <= 0xbffff))
mem_log("Exec allowed: %08X (mapping for %08X)\n", map, start);
#endif
mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x))
_mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base);
}
if ((map->write_b || map->write_w || map->write_l) &&
mem_mapping_write_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS])) {
#ifdef ENABLE_MEM_LOG
if ((start >= 0xa0000) && (start <= 0xbffff))
mem_log("Write allowed: %08X (mapping for %08X)\n", map, start);
#endif
mem_mapping_access_allowed(map->flags, _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w))
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;
@@ -2437,37 +2325,40 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
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 ((base_mapping == NULL) && (last_mapping != NULL)) {
fatal("mem_mapping_del(): NULL base mapping with non-NULL last mapping\n");
return;
} else if ((base_mapping != NULL) && (last_mapping == NULL)) {
fatal("mem_mapping_del(): Non-NULL base mapping with NULL last mapping\n");
return;
} else if ((base_mapping != NULL) && (base_mapping->prev != NULL)) {
fatal("mem_mapping_del(): Base mapping with a preceding mapping\n");
return;
} else if ((last_mapping != NULL) && (last_mapping->next != NULL)) {
fatal("mem_mapping_del(): Last mapping with a following mapping\n");
return;
}
if (size != 0x00000000)
map->enable = 1;
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->next = NULL;
mem_log("mem_mapping_add(): Linked list structure: %08X -> %08X -> %08X\n", map->prev, map, map->next);
/* Disable the entry. */
mem_mapping_disable(map);
/* 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;
/* If the mapping is disabled, there is no need to recalc anything. */
if (size != 0x00000000)
mem_mapping_recalc(map->base, map->size);
}
@@ -2513,28 +2404,8 @@ mem_mapping_add(mem_mapping_t *map,
}
last_mapping = map;
if (size != 0x00000000)
map->enable = 1;
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);
mem_mapping_set(map, base, size, read_b, read_w, read_l,
write_b, write_w, write_l, exec, fl, p);
}
@@ -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
mem_mapping_disable(mem_mapping_t *map)
{
@@ -2623,47 +2487,40 @@ mem_mapping_enable(mem_mapping_t *map)
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) {
mask_l = 0xffff0f0f;
mask_h = 0x0f0fffff;
} else {
mask_l = 0xfffff0f0;
mask_h = 0xf0f0ffff;
}
if (mode)
mask = 0x2d6b;
else
mask = 0x1084;
if (mode) {
if (mode == 1)
state = !!state;
access = !!access;
switch (state & 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;
}
smstate = smstates[access & 0x03];
} else
smstate = state & 0x0f0f;
smstate = access & 0x6f7b;
for (c = 0; c < size; c += MEM_GRANULARITY_SIZE) {
if (smm != 0)
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & mask_h) | (smstate << MEM_STATE_SMM_SHIFT);
if (smm != 1)
_mem_state[(c + base) >> MEM_GRANULARITY_BITS] = (_mem_state[(c + base) >> MEM_GRANULARITY_BITS] & mask_l) | smstate;
for (i = 0; i < 4; i++) {
if (bitmap & (1 << i)) {
_mem_state[(c + base) >> MEM_GRANULARITY_BITS].vals[i] =
(_mem_state[(c + base) >> MEM_GRANULARITY_BITS].vals[i] & mask) | smstate;
}
}
#ifdef ENABLE_MEM_LOG
if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff))
mem_log("Set mem state for block at %08X to %02X\n", c + base, smstate);
if (((c + base) >= 0xa0000) && ((c + base) <= 0xbffff)) {
mem_log("Set mem state for block at %08X to %04X with bitmap %02X\n",
c + base, smstate, bitmap);
}
#endif
}
@@ -2694,7 +2551,7 @@ mem_close(void)
while (map != NULL) {
next = map->next;
mem_mapping_del(map);
map->prev = map->next = NULL;
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. */
void
mem_reset(void)
{
uint32_t c, m, m2;
uint32_t c, m;
memset(page_ff, 0xff, sizeof(page_ff));
@@ -2778,14 +2653,6 @@ mem_reset(void)
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.
* 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_w = mem_write_ramw_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
pages[c].evict_prev = EVICT_NOT_IN_LIST;
@@ -2850,44 +2711,27 @@ mem_reset(void)
#endif
}
memset(read_mapping, 0x00, sizeof(read_mapping));
memset(write_mapping, 0x00, sizeof(write_mapping));
memset(_mem_exec, 0x00, sizeof(_mem_exec));
memset(write_mapping, 0x00, sizeof(write_mapping));
memset(read_mapping, 0x00, sizeof(read_mapping));
memset(write_mapping_bus, 0x00, sizeof(write_mapping_bus));
memset(read_mapping_bus, 0x00, sizeof(read_mapping_bus));
base_mapping = last_mapping = NULL;
/* 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. */
mem_set_mem_state_both(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);
mem_init_ram_mapping(&ram_low_mapping, 0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024);
if (mem_size > 1024) {
if (cpu_16bitbus && mem_size > 16256) {
mem_set_mem_state_both(0x100000, (16256 - 1024) * 1024,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_mapping_add(&ram_high_mapping, 0x100000,
((16256 - 1024) * 1024),
mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml,
ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
} else {
if (cpu_16bitbus && mem_size > 16256)
mem_init_ram_mapping(&ram_high_mapping, 0x100000, (16256 - 1024) * 1024);
else {
if (mem_size > 1048576) {
mem_set_mem_state_both(0x100000, (1048576 - 1024) * 1024,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_mapping_add(&ram_high_mapping, 0x100000,
((1048576 - 1024) * 1024),
mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml,
ram + 0x100000, MEM_MAPPING_INTERNAL, NULL);
mem_init_ram_mapping(&ram_high_mapping, 0x100000, (1048576 - 1024) * 1024);
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),
@@ -2895,24 +2739,13 @@ mem_reset(void)
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);
}
} else
mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024);
}
}
if (mem_size > 768) {
mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000,
mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml,
ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
}
if (mem_size > 768)
mem_add_ram_mapping(&ram_mid_mapping, 0xa0000, 0x60000);
mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
mem_read_remapped,mem_read_remappedw,mem_read_remappedl,
@@ -2953,16 +2786,17 @@ mem_remap_top(int kb)
uint32_t c;
uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
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);
if (mem_size <= 640) return;
if (kb == 0) {
/* Called to disable the mapping. */
mem_mapping_disable(&ram_remapped_mapping);
return;
}
kb = old_kb;
set = 0;
} else
old_kb = kb;
if (size > kb)
size = kb;
@@ -2971,10 +2805,10 @@ mem_remap_top(int kb)
for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) {
offset = c - ((start * 1024) >> 12);
pages[c].mem = &ram[0xA0000 + (offset << 12)];
pages[c].write_b = mem_write_ramb_page;
pages[c].write_w = mem_write_ramw_page;
pages[c].write_l = mem_write_raml_page;
pages[c].mem = set ? &ram[0xa0000 + (offset << 12)] : page_ff;
pages[c].write_b = set ? mem_write_ramb_page : NULL;
pages[c].write_w = set ? mem_write_ramw_page : NULL;
pages[c].write_l = set ? mem_write_raml_page : NULL;
#ifdef USE_NEW_DYNAREC
pages[c].evict_prev = EVICT_NOT_IN_LIST;
pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64];
@@ -2982,10 +2816,14 @@ mem_remap_top(int kb)
#endif
}
mem_set_mem_state_both(start * 1024, size * 1024,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
(MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL));
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();
}

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
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,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM, rom);
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0);
}