Merge remote-tracking branch 'upstream/master' into CD_ROM_Batch
This commit is contained in:
@@ -231,6 +231,8 @@ typedef struct neat_t {
|
||||
uint16_t ems_size; /* EMS size in KB */
|
||||
uint16_t ems_pages; /* EMS size in pages */
|
||||
|
||||
uint32_t remap_base;
|
||||
|
||||
ram_page_t ems[EMS_MAXPAGE]; /* EMS page registers */
|
||||
ram_page_t shadow[32]; /* Shadow RAM pages */
|
||||
} neat_t;
|
||||
@@ -238,6 +240,9 @@ typedef struct neat_t {
|
||||
static uint8_t defaults[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0xa0, 0x63, 0x10, 0x00, 0x00, 0x12 };
|
||||
|
||||
static uint8_t masks[4] = { RB10_P0EXT, RB10_P1EXT, RB10_P2EXT, RB10_P3EXT };
|
||||
static uint8_t shifts[4] = { RB10_P0EXT_SH, RB10_P1EXT_SH, RB10_P2EXT_SH, RB10_P3EXT_SH };
|
||||
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
int neat_do_log = ENABLE_NEAT_LOG;
|
||||
|
||||
@@ -262,10 +267,17 @@ ems_readb(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
uint32_t old = addr;
|
||||
#endif
|
||||
|
||||
/* Grab the data. */
|
||||
ret = *(uint8_t *) &(ram[addr - dev->virt_base + dev->phys_base]);
|
||||
addr = addr - dev->virt_base + dev->phys_base;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint8_t *) &(ram[addr]);
|
||||
|
||||
neat_log("[R08] %08X -> %08X (%08X): ret = %02X\n", old, addr, (mem_size << 10), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -275,10 +287,17 @@ ems_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
uint32_t old = addr;
|
||||
#endif
|
||||
|
||||
/* Grab the data. */
|
||||
ret = *(uint16_t *) &(ram[addr - dev->virt_base + dev->phys_base]);
|
||||
addr = addr - dev->virt_base + dev->phys_base;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint16_t *) &(ram[addr]);
|
||||
|
||||
neat_log("[R16] %08X -> %08X (%08X): ret = %04X\n", old, addr, (mem_size << 10), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -287,9 +306,16 @@ static void
|
||||
ems_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
uint32_t old = addr;
|
||||
#endif
|
||||
|
||||
/* Write the data. */
|
||||
*(uint8_t *) &(ram[addr - dev->virt_base + dev->phys_base]) = val;
|
||||
addr = addr - dev->virt_base + dev->phys_base;
|
||||
neat_log("[W08] %08X -> %08X (%08X): val = %02X\n", old, addr, (mem_size << 10), val);
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint8_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
/* Write one word to paged RAM. */
|
||||
@@ -297,9 +323,16 @@ static void
|
||||
ems_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
uint32_t old = addr;
|
||||
#endif
|
||||
|
||||
/* Write the data. */
|
||||
*(uint16_t *) &(ram[addr - dev->virt_base + dev->phys_base]) = val;
|
||||
addr = addr - dev->virt_base + dev->phys_base;
|
||||
neat_log("[W16] %08X -> %08X (%08X): val = %04X\n", old, addr, (mem_size << 10), val);
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -379,10 +412,11 @@ shadow_recalc(neat_t *dev)
|
||||
static void
|
||||
ems_recalc(neat_t *dev, ram_page_t *ems)
|
||||
{
|
||||
uint32_t page = ems->phys_base / EMS_PGSIZE;
|
||||
uint32_t page = ems->phys_base / EMS_PGSIZE;
|
||||
|
||||
if ((dev->regs[REG_RB7] & RB7_EMSEN) && ems->enabled &&
|
||||
(page >= 0x40) && (page < (0x40 + dev->ems_pages))) {
|
||||
neat_log("ems_recalc(): %08X, %04X, %04X\n", ems->virt_base, page, dev->ems_pages);
|
||||
|
||||
if ((dev->regs[REG_RB7] & RB7_EMSEN) && ems->enabled && (page < dev->ems_pages)) {
|
||||
neat_log("ems_recalc(): %08X-%08X -> %08X-%08X\n",
|
||||
ems->virt_base, ems->virt_base + EMS_PGSIZE - 1,
|
||||
ems->phys_base, ems->phys_base + EMS_PGSIZE - 1);
|
||||
@@ -405,14 +439,20 @@ ems_recalc(neat_t *dev, ram_page_t *ems)
|
||||
if ((ems->virt_base >= 0x00080000) && (ems->virt_base < 0x00100000))
|
||||
neat_mem_update_state(dev, ems->virt_base, EMS_PGSIZE, 0x00, RAM_FMASK_EMS);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
ems_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
ram_page_t *ems;
|
||||
int vpage;
|
||||
int8_t old_enabled;
|
||||
uint32_t old_phys_base;
|
||||
int8_t new_enabled;
|
||||
uint32_t new_phys_base;
|
||||
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: ems_write(%04x, %02x)\n", port, val);
|
||||
@@ -422,12 +462,29 @@ ems_write(uint16_t port, uint8_t val, void *priv)
|
||||
vpage = (port / EMS_PGSIZE);
|
||||
ems = &dev->ems[vpage];
|
||||
|
||||
neat_log("Port: %04X, val: %02X\n", port, val);
|
||||
|
||||
switch (port & 0x000f) {
|
||||
case 0x0008:
|
||||
case 0x0009:
|
||||
ems->enabled = !!(val & 0x80);
|
||||
ems->phys_base = (ems->phys_base & 0xffe00000) | ((val & 0x7f) * EMS_PGSIZE);
|
||||
ems_recalc(dev, ems);
|
||||
old_enabled = ems->enabled;
|
||||
old_phys_base = ems->phys_base;
|
||||
new_enabled = !!(val & 0x80);
|
||||
new_phys_base = (ems->phys_base & 0xffe00000) | ((val & 0x7f) * EMS_PGSIZE);
|
||||
|
||||
if ((old_enabled != new_enabled) || (old_phys_base != new_phys_base)) {
|
||||
if (old_enabled && (old_enabled == new_enabled)) {
|
||||
ems->enabled = 0;
|
||||
ems_recalc(dev, ems);
|
||||
}
|
||||
|
||||
ems->enabled = !!(val & 0x80);
|
||||
|
||||
if (old_phys_base != new_phys_base)
|
||||
ems->phys_base = (ems->phys_base & 0xffe00000) | ((val & 0x7f) * EMS_PGSIZE);
|
||||
|
||||
ems_recalc(dev, ems);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -454,6 +511,8 @@ ems_read(uint16_t port, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
neat_log("Port: %04X, ret: %02X\n", port, ret);
|
||||
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: ems_read(%04x) = %02x\n", port, ret);
|
||||
#endif
|
||||
@@ -462,20 +521,76 @@ ems_read(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
static void
|
||||
ems_update(neat_t *dev, int en)
|
||||
ems_recalc_all(neat_t *dev)
|
||||
{
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++)
|
||||
ems_recalc(dev, &(dev->ems[i]));
|
||||
}
|
||||
|
||||
static void
|
||||
ems_update_virt_base(neat_t *dev)
|
||||
{
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++)
|
||||
dev->ems[i].virt_base = dev->ems_frame + (i * EMS_PGSIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
ems_remove_handlers(neat_t *dev)
|
||||
{
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
neat_log("Removing I/O handler at %04X-%04X\n",
|
||||
dev->ems_base + (i * EMS_PGSIZE), dev->ems_base + (i * EMS_PGSIZE) + 1);
|
||||
/* Clean up any previous I/O port handler. */
|
||||
io_removehandler(dev->ems_base + (i * EMS_PGSIZE), 2,
|
||||
ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ems_set_handlers(neat_t *dev)
|
||||
{
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
neat_log("Setting up I/O handler at %04X-%04X\n",
|
||||
dev->ems_base + (i * EMS_PGSIZE), dev->ems_base + (i * EMS_PGSIZE) + 1);
|
||||
/* Set up an I/O port handler. */
|
||||
io_handler(en, dev->ems_base + (i * EMS_PGSIZE), 2,
|
||||
ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
|
||||
|
||||
if (en)
|
||||
dev->ems[i].virt_base = dev->ems_frame + (i * EMS_PGSIZE);
|
||||
|
||||
ems_recalc(dev, &(dev->ems[i]));
|
||||
io_sethandler(dev->ems_base + (i * EMS_PGSIZE), 2,
|
||||
ems_read, NULL, NULL, ems_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
ems_recalc_all(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
remap_update(neat_t *dev, uint8_t val)
|
||||
{
|
||||
if (dev->regs[REG_RB7] & RB7_UMAREL) {
|
||||
mem_remap_top_ex(0, (dev->remap_base >= 1024) ? dev->remap_base : 1024);
|
||||
neat_log("0 kB at %08X\n", ((dev->remap_base >= 1024) ? dev->remap_base : 1024) << 10);
|
||||
}
|
||||
|
||||
if (val & RB7_EMSEN)
|
||||
dev->remap_base = mem_size - dev->ems_size;
|
||||
else
|
||||
dev->remap_base = mem_size;
|
||||
neat_log("Total contiguous memory now: %i kB\n", dev->remap_base);
|
||||
|
||||
if (dev->remap_base >= 640)
|
||||
mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000);
|
||||
else
|
||||
mem_mapping_set_addr(&ram_low_mapping, 0x00000000, dev->remap_base << 10);
|
||||
|
||||
if (dev->remap_base > 1024)
|
||||
mem_mapping_set_addr(&ram_high_mapping, 0x00100000, (dev->remap_base << 10) - 0x00100000);
|
||||
else
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
|
||||
if (val & RB7_UMAREL) {
|
||||
mem_remap_top_ex(384, (dev->remap_base >= 1024) ? dev->remap_base : 1024);
|
||||
neat_log("384 kB at %08X\n", ((dev->remap_base >= 1024) ? dev->remap_base : 1024) << 10);
|
||||
}
|
||||
|
||||
/* Yes, this has to be done on every step because mem_remap_top_ex() reenables it. */
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -590,20 +705,21 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case REG_RB7:
|
||||
val &= RB7_MASK;
|
||||
*reg = val;
|
||||
|
||||
if (xval & (RB7_EMSEN | RB7_UMAREL))
|
||||
remap_update(dev, val);
|
||||
|
||||
dev->regs[REG_RB7] = val;
|
||||
|
||||
if (xval & RB7_EMSEN)
|
||||
ems_remove_handlers(dev);
|
||||
|
||||
if ((xval & RB7_EMSEN) && (val & RB7_EMSEN))
|
||||
ems_set_handlers(dev);
|
||||
|
||||
#if NEAT_DEBUG > 1
|
||||
neat_log("NEAT: RB7=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
|
||||
if (xval & RB7_EMSEN)
|
||||
ems_update(dev, !!(val & RB7_EMSEN));
|
||||
|
||||
if (xval & RB7_UMAREL) {
|
||||
if (val & RB7_UMAREL)
|
||||
mem_remap_top(384);
|
||||
else
|
||||
mem_remap_top(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_RB8:
|
||||
@@ -621,18 +737,20 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
neat_log("NEAT: RB9=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
|
||||
ems_update(dev, 0);
|
||||
ems_remove_handlers(dev);
|
||||
|
||||
/* Get configured I/O address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
|
||||
/* Get configured frame address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
|
||||
dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j);
|
||||
|
||||
ems_update_virt_base(dev);
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
ems_update(dev, 1);
|
||||
ems_set_handlers(dev);
|
||||
break;
|
||||
|
||||
case REG_RB10:
|
||||
@@ -642,18 +760,32 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
neat_log("NEAT: RB10=%02x(%02x)\n", val, *reg);
|
||||
#endif
|
||||
|
||||
dev->ems[3].phys_base = (dev->ems[3].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P3EXT) >> RB10_P3EXT_SH) << 21);
|
||||
dev->ems[2].phys_base = (dev->ems[2].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P2EXT) >> RB10_P2EXT_SH) << 21);
|
||||
dev->ems[1].phys_base = (dev->ems[1].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P1EXT) >> RB10_P1EXT_SH) << 21);
|
||||
dev->ems[0].phys_base = (dev->ems[0].phys_base & 0x001fffff) |
|
||||
(((val & RB10_P0EXT) >> RB10_P0EXT_SH) << 21);
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
ram_page_t *ems = &(dev->ems[i]);
|
||||
|
||||
uint32_t old_phys_base = ems->phys_base & 0xffe00000;
|
||||
uint32_t new_phys_base = (((val & masks[i]) >> shifts[i]) << 21);
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
for (i = 0; i < EMS_MAXPAGE; i++)
|
||||
ems_recalc(dev, &dev->ems[i]);
|
||||
if (new_phys_base != old_phys_base) {
|
||||
int8_t old_enabled = ems->enabled;
|
||||
|
||||
if ((dev->regs[REG_RB7] & RB7_EMSEN) && old_enabled) {
|
||||
ems->enabled = 0;
|
||||
ems_recalc(dev, &(dev->ems[i]));
|
||||
}
|
||||
|
||||
ems->phys_base = ems->phys_base - old_phys_base + new_phys_base;
|
||||
|
||||
if ((dev->regs[REG_RB7] & RB7_EMSEN) && old_enabled) {
|
||||
ems->enabled = old_enabled;
|
||||
ems_recalc(dev, &(dev->ems[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
neat_log("%08X, %08X, %08X, %08X\n",
|
||||
dev->ems[0].phys_base, dev->ems[1].phys_base,
|
||||
dev->ems[2].phys_base, dev->ems[3].phys_base);
|
||||
break;
|
||||
|
||||
case REG_RB12:
|
||||
@@ -680,15 +812,12 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE;
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
for (i = 0; i < EMS_MAXPAGE; i++)
|
||||
ems_recalc(dev, &dev->ems[i]);
|
||||
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN) {
|
||||
neat_log("NEAT: EMS %iKB (%i pages)\n",
|
||||
dev->ems_size, dev->ems_pages);
|
||||
remap_update(dev, dev->regs[REG_RB7]);
|
||||
|
||||
neat_log("NEAT: EMS %iKB\n",
|
||||
dev->ems_size);
|
||||
}
|
||||
|
||||
mem_a20_key = val & RB12_GA20;
|
||||
@@ -756,12 +885,17 @@ neat_init(UNUSED(const device_t *info))
|
||||
memset(dev, 0x00, sizeof(neat_t));
|
||||
|
||||
/* Get configured I/O address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
|
||||
dev->ems_base = 0x0208 + (0x10 * j);
|
||||
|
||||
/* Get configured frame address. */
|
||||
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
|
||||
dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j);
|
||||
j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
|
||||
dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j);
|
||||
|
||||
ems_update_virt_base(dev);
|
||||
|
||||
dev->ems_pages = (mem_size << 10) / EMS_PGSIZE;
|
||||
dev->remap_base = mem_size;
|
||||
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
|
||||
@@ -773,10 +907,10 @@ neat_init(UNUSED(const device_t *info))
|
||||
for (uint8_t i = 0; i < EMS_MAXPAGE; i++) {
|
||||
/* Create and initialize a page mapping. */
|
||||
mem_mapping_add(&dev->ems[i].mapping,
|
||||
dev->ems_frame + (EMS_PGSIZE * i), EMS_PGSIZE,
|
||||
0x00000000, 0x00000000,
|
||||
ems_readb, ems_readw, NULL,
|
||||
ems_writeb, ems_writew, NULL,
|
||||
ram, MEM_MAPPING_INTERNAL,
|
||||
ram + dev->ems[i].virt_base, MEM_MAPPING_INTERNAL,
|
||||
&(dev->ems[i]));
|
||||
|
||||
/* Disable for now. */
|
||||
|
||||
@@ -3597,7 +3597,7 @@ const machine_t machines[] = {
|
||||
.flags = MACHINE_IDE | MACHINE_VIDEO,
|
||||
.ram = {
|
||||
.min = 512,
|
||||
.max = 16384,
|
||||
.max = 5120,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
@@ -3637,7 +3637,7 @@ const machine_t machines[] = {
|
||||
.flags = MACHINE_FLAGS_NONE,
|
||||
.ram = {
|
||||
.min = 512,
|
||||
.max = 16384,
|
||||
.max = 8192,
|
||||
.step = 128
|
||||
},
|
||||
.nvrmask = 127,
|
||||
|
||||
Reference in New Issue
Block a user