diff --git a/src/86box.c b/src/86box.c index 7ede5d857..52f626bd2 100644 --- a/src/86box.c +++ b/src/86box.c @@ -726,6 +726,8 @@ pc_reset_hard_close(void) closeal(); video_reset_close(); + + cpu_close(); } @@ -981,56 +983,56 @@ pc_onesec(void) void set_screen_size(int x, int y) { - int owsx = scrnsz_x; - int owsy = scrnsz_y; - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; - double dx, dy, dtx, dty; + int owsx = scrnsz_x; + int owsy = scrnsz_y; + int temp_overscan_x = overscan_x; + int temp_overscan_y = overscan_y; + double dx, dy, dtx, dty; - /* Make sure we keep usable values. */ + /* Make sure we keep usable values. */ #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 - if (x < 320) x = 320; - if (y < 200) y = 200; - if (x > 2048) x = 2048; - if (y > 2048) y = 2048; + if (x < 320) x = 320; + if (y < 200) y = 200; + if (x > 2048) x = 2048; + if (y > 2048) y = 2048; - /* Save the new values as "real" (unscaled) resolution. */ - unscaled_size_x = x; - efscrnsz_y = y; + /* Save the new values as "real" (unscaled) resolution. */ + unscaled_size_x = x; + efscrnsz_y = y; - if (suppress_overscan) - temp_overscan_x = temp_overscan_y = 0; + if (suppress_overscan) + temp_overscan_x = temp_overscan_y = 0; - if (force_43) { - dx = (double)x; - dtx = (double)temp_overscan_x; + if (force_43) { + dx = (double)x; + dtx = (double)temp_overscan_x; - dy = (double)y; - dty = (double)temp_overscan_y; + dy = (double)y; + dty = (double)temp_overscan_y; - /* Account for possible overscan. */ - if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) { - /* CGA */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) { - /* MDA/Hercules */ - dy = (x / 4.0) * 3.0; - } else { - if (enable_overscan) { - /* EGA/(S)VGA with overscan */ - dy = (((dx - dtx) / 4.0) * 3.0) + dty; - } else { - /* EGA/(S)VGA without overscan */ - dy = (x / 4.0) * 3.0; - } - } - unscaled_size_y = (int)dy; - } else + /* Account for possible overscan. */ + if (!(video_is_ega_vga()) && (temp_overscan_y == 16)) { + /* CGA */ + dy = (((dx - dtx) / 4.0) * 3.0) + dty; + } else if (!(video_is_ega_vga()) && (temp_overscan_y < 16)) { + /* MDA/Hercules */ + dy = (x / 4.0) * 3.0; + } else { + if (enable_overscan) { + /* EGA/(S)VGA with overscan */ + dy = (((dx - dtx) / 4.0) * 3.0) + dty; + } else { + /* EGA/(S)VGA without overscan */ + dy = (x / 4.0) * 3.0; + } + } + unscaled_size_y = (int)dy; + } else unscaled_size_y = efscrnsz_y; - switch(scale) { + switch(scale) { case 0: /* 50% */ scrnsz_x = (unscaled_size_x>>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_y = (unscaled_size_y<<1); break; - } + } - /* If the resolution has changed, let the main thread handle it. */ - if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) + /* If the resolution has changed, let the main thread handle it. */ + if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) doresize = 1; - else + else doresize = 0; } diff --git a/src/acpi.c b/src/acpi.c index bcb81cb4c..a8f5ec4ea 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -124,6 +124,8 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p) ret = (dev->regs.pmsts >> shift16) & 0xff; if (addr == 0x01) ret |= (acpi_rtc_status << 2); + else + ret |= 0x10; break; case 0x02: case 0x03: /* 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) */ ret = (dev->regs.pmcntrl >> shift16) & 0xff; if (addr == 0x05) - ret = (ret & 0xdf) | 0x02; /* Bit 5 is write-only. */ + ret = (ret & 0xdf); /* Bit 5 is write-only. */ break; case 0x08: case 0x09: case 0x0a: case 0x0b: /* PMTMR - Power Management Timer Register (IO) */ @@ -152,6 +154,7 @@ acpi_reg_read_common_regs(int size, uint16_t addr, void *p) return ret; } + static uint32_t 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; } + static uint32_t 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) */ ret = (dev->regs.glbsts >> shift16) & 0xff; if (addr == 0x18) { - ret &= 0x25; + ret &= 0x27; if (dev->regs.gpsts != 0x0000) ret |= 0x80; if (dev->regs.pmsts != 0x0000) @@ -288,8 +292,8 @@ acpi_reg_read_intel(int size, uint16_t addr, void *p) } #ifdef ENABLE_ACPI_LOG - if (size != 1) - acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); + // if (size != 1) + // acpi_log("(%i) ACPI Read (%i) %02X: %02X\n", in_smm, size, addr, ret); #endif return ret; } @@ -635,8 +639,8 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) break; case 0x04: case 0x05: /* PMCNTRL - Power Management Control Register (IO) */ - if ((addr == 0x05) && (dev->regs.pmcntrl & 0x2000)) { - sus_typ = (dev->regs.pmcntrl >> 10) & 7; + if ((addr == 0x05) && (val & 0x20)) { + sus_typ = (val >> 2) & 7; switch (sus_typ) { case 0: /* Soft power off. */ @@ -662,15 +666,16 @@ acpi_reg_write_common_regs(int size, uint16_t addr, uint8_t val, void *p) resetx86(); break; 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; } } 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; } } + static void 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 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) */ dev->regs.gpen = ((dev->regs.gpen & ~(0xff << shift16)) | (val << shift16)) & 0x0f01; break; - case 0x10: case 0x11: case 0x12: case 0x13: + case 0x10: case 0x11: case 0x13: /* PCNTRL - Processor Control Register (IO) */ dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00023e1e; break; + case 0x12: + /* PCNTRL - Processor Control Register (IO) */ + dev->regs.pcntrl = ((dev->regs.pcntrl & ~(0xfd << shift32)) | (val << shift32)) & 0x00023e1e; + break; case 0x18: case 0x19: /* GLBSTS - Global Status Register (IO) */ - dev->regs.glbsts &= ~((val << shift16) & 0x0df7); + dev->regs.glbsts &= ~((val << shift16) & 0x0dd7); break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: /* DEVSTS - Device Status Register (IO) */ diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 116977764..862eae81d 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -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); diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index a7c18f60b..de8c5a028 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -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) { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 177712fa7..35209bc1a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -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); diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 763ca1358..8f5798ddb 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -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 { diff --git a/src/device/isamem.c b/src/device/isamem.c index 76080c328..cc680d9a3 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -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); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 07d89c406..700c92981 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -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); diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index 49c5f1e5d..08ab241cf 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -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); diff --git a/src/mem/mem.c b/src/mem/mem.c index 1d54d7880..374062c1b 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -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) - ret = map->read_b(addr, map->p); + 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) - map->write_b(addr, val, map->p); + 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; + 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 (!(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); - - 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 = 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) { + /* In range? */ + 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(_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_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); - mem_mapping_set_exec(&ram_remapped_mapping, ram + 0xa0000); + 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(); } diff --git a/src/mem/rom.c b/src/mem/rom.c index 477974d96..efb173d0b 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -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); }