From f6eae8c6581b978554abb07ae75008871750eb41 Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 25 Aug 2018 14:52:23 -0400 Subject: [PATCH] Initial release of the ISA Memory Expansion Card driver. Not done yet, but works. --- src/config.c | 65 +-- src/devices/misc/isamem.c | 994 ++++++++++++++++++++++++++++++++++ src/devices/misc/isamem.h | 77 +++ src/emu.h | 5 +- src/pc.c | 9 +- src/win/VARCem-common.rc | 22 +- src/win/mingw/Makefile.MinGW | 3 +- src/win/msvc/Makefile.VC | 3 +- src/win/resource.h | 93 ++-- src/win/win_settings.c | 38 +- src/win/win_settings_periph.h | 58 +- 11 files changed, 1261 insertions(+), 106 deletions(-) create mode 100644 src/devices/misc/isamem.c create mode 100644 src/devices/misc/isamem.h diff --git a/src/config.c b/src/config.c index 4eeb9ff..b48166a 100644 --- a/src/config.c +++ b/src/config.c @@ -12,7 +12,7 @@ * it on Windows XP, and possibly also Vista. Use the * -DANSI_CFG for use on these systems. * - * Version: @(#)config.c 1.0.29 2018/06/06 + * Version: @(#)config.c 1.0.31 2018/08/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -53,6 +53,7 @@ #include "machines/machine.h" #include "nvr.h" #include "device.h" +#include "devices/misc/isamem.h" #include "devices/ports/game_dev.h" #include "devices/ports/serial.h" #include "devices/ports/parallel.h" @@ -409,9 +410,11 @@ load_machine(const char *cat) cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); mem_size = config_get_int(cat, "mem_size", 4096); +#if 0 if (mem_size < (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); +#endif if (mem_size > 1048576) mem_size = 1048576; @@ -477,13 +480,6 @@ load_video(const char *cat) video_card = VID_INTERNAL; } else { p = config_get_string(cat, "video_card", NULL); - - /* Remove this after 01-JUL-2018. --FvK */ - if (p == NULL) { - p = config_get_string(cat, "gfxcard", NULL); - if (p != NULL) - config_delete_var(cat, "gfxcard"); - } if (p == NULL) { if (machines[machine].flags & MACHINE_VIDEO) p = "internal"; @@ -622,17 +618,7 @@ load_sound(const char *cat) { char *p; - p = config_get_string(cat, "sound_card", NULL); - - /* Remove this after 01-JUL-2018. --FvK */ - if (p == NULL) { - p = config_get_string(cat, "sndcard", NULL); - if (p != NULL) - config_delete_var(cat, "sndcard"); - } - - if (p == NULL) - p = "none"; + p = config_get_string(cat, "sound_card", "none"); sound_card = sound_card_get_from_internal_name(p); p = config_get_string(cat, "midi_device", "none"); @@ -837,17 +823,7 @@ load_other(const char *cat) char temp[512], *p; int c; - p = config_get_string(cat, "scsi_card", NULL); - - /* Remove this after 01-JUL-2018. --FvK */ - if (p == NULL) { - p = config_get_string(cat, "scsicard", NULL); - if (p != NULL) - config_delete_var(cat, "scsicard"); - } - - if (p == NULL) - p = "none"; + p = config_get_string(cat, "scsi_card", "none"); scsi_card = scsi_card_get_from_internal_name(p); p = config_get_string(cat, "hdc", NULL); @@ -859,7 +835,7 @@ load_other(const char *cat) } hdc_type = hdc_get_from_internal_name(p); - for (c=2; c<4; c++) { + for (c = 2; c < 4; c++) { sprintf(temp, "ide_%02i", c + 1); p = config_get_string(cat, temp, "0, 00"); sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]); @@ -867,6 +843,13 @@ load_other(const char *cat) bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); + for (c = 0; c < ISAMEM_MAX; c++) { + sprintf(temp, "isamem%d_type", c); + + p = config_get_string(cat, temp, "none"); + isamem_type[c] = isamem_get_from_internal_name(p); + } + #ifdef WALTJE romdos_enabled = !!config_get_int(cat, "romdos_enabled", 0); #endif @@ -902,6 +885,15 @@ save_other(const char *cat) else config_set_int(cat, "bugger_enabled", bugger_enabled); + for (c = 0; c < ISAMEM_MAX; c++) { + sprintf(temp, "isamem%d_type", c); + if (isamem_type[c] == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, + isamem_get_internal_name(isamem_type[c])); + } + delete_section_if_empty(cat); } @@ -996,16 +988,7 @@ load_disks(const char *cat) if (hdd[c].bus == HDD_BUS_ST506) { /* Try new syntax. */ dev = config_get_int(cat, temp, -1); - if (dev < 0) { - /* Re-try with old syntax. */ - // FIXME: remove by 01-JUL-2018 --FvK - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - dev = config_get_int(cat, temp, c & 1); - config_delete_var(cat, temp); - - /* Set value either way. */ - hdd[c].id.st506_channel = dev; - } + hdd[c].id.st506_channel = dev; } else config_delete_var(cat, temp); diff --git a/src/devices/misc/isamem.c b/src/devices/misc/isamem.c new file mode 100644 index 0000000..060adf9 --- /dev/null +++ b/src/devices/misc/isamem.c @@ -0,0 +1,994 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Implementation of a memory expansion board for the ISA Bus. + * + * Although modern systems use direct-connect local buses to + * connect the CPU with its memory, originally the main system + * bus(es) were used for that. Memory expension cards could add + * memory to the system through the ISA bus, using a variety of + * techniques. + * + * The majority of these boards could provide some (additional) + * conventional (low) memory, extended (high) memory on 80286 + * and higher systems, as well as EMS bank-switched memory. + * + * This implementation uses the LIM 3.2 specifications for EMS. + * + * With the EMS method, the system's standard memory is expanded + * by means of bank-switching. One or more 'frames' in the upper + * memory area (640K-1024K) are used as viewports into an array + * of RAM pages numbered 0 to N. Each page is defined to be 16KB + * in size, so, for a 1024KB board, 64 such pages are available. + * I/O control registers are used to set up the mappings. More + * modern boards even have multiple 'copies' of those registers, + * which can be switched very fast, to allow for multitasking. + * + * TODO: The EV159 is supposed to support 16b EMS transfers, but the + * EMM.sys driver for it doesn't seem to want to do that.. + * + * Version: @(#)isamem.c 1.0.1 2018/08/18 + * + * Author: Fred N. van Kempen, + * + * Copyright 2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include "../../emu.h" +#include "../../cpu/cpu.h" +#include "../../machines/machine.h" +#include "../../io.h" +#include "../../mem.h" +#include "../../device.h" +#include "../../ui/ui.h" +#include "../../plat.h" +#include "isamem.h" + + +#define RAM_TOPMEM (640 << 10) /* end of low memory */ +#define RAM_UMAMEM (384 << 10) /* upper memory block */ +#define RAM_EXTMEM (1024 << 10) /* start of high memory */ + +#define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ +#define EMS_PGSIZE (16 << 10) /* one page is this big */ +#define EMS_MAXPAGE 4 /* number of viewport pages */ + + +typedef struct { + int8_t enabled; /* 1=ENABLED */ + uint8_t page; /* page# in EMS RAM */ + uint8_t frame; /* (varies with board) */ + char pad; + uint8_t *addr; /* start addr in EMS RAM */ + mem_mapping_t mapping; /* mapping entry for page */ +} emsreg_t; + +typedef struct { + const char *name; + uint8_t board : 6, /* board type */ + instance : 2; /* device instance */ + + uint8_t flags; +#define FLAG_CONFIG 0x01 /* card is configured */ +#define FLAG_WIDE 0x10 /* card uses 16b mode */ +#define FLAG_FAST 0x20 /* fast (<= 120ns) chips */ +#define FLAG_EMS 0x40 /* card has EMS mode enabled */ + + uint16_t total_size; /* configured size in KB */ + uint32_t base_addr, /* configured I/O address */ + start_addr, /* configured memory start */ + frame_addr; /* configured frame address */ + + uint16_t ems_size, /* EMS size in KB */ + ems_pages; /* EMS size in pages */ + uint32_t ems_start; /* start of EMS in RAM */ + + uint8_t *ram; /* allocated RAM buffer */ + + mem_mapping_t low_mapping; /* mapping for low mem */ + mem_mapping_t high_mapping; /* mapping for high mem */ + + emsreg_t ems[EMS_MAXPAGE]; /* EMS controller registers */ +} memdev_t; + + +/* Local variables. */ +static const device_t *instance[ISAMEM_MAX] = { + NULL, + NULL, + NULL, + NULL +}; + + +/* 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; + uint8_t ret = 0xff; + + /* Grab the data. */ + ret = *(uint8_t *)(dev->ram + (addr - map->base)); + + return(ret); +} + + +/* Read one word from onboard RAM. */ +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; + uint16_t ret = 0xffff; + + /* Grab the data. */ + ret = *(uint16_t *)(dev->ram + (addr - map->base)); + + return(ret); +} + + +/* Write one byte to onboard RAM. */ +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; + + /* Write the data. */ + *(uint8_t *)(dev->ram + (addr - map->base)) = val; +} + + +/* Write one word to onboard RAM. */ +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; + + /* Write the data. */ + *(uint16_t *)(dev->ram + (addr - map->base)) = val; +} + + +/* Read one byte from onboard paged RAM. */ +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; + 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)); + + return(ret); +} + + +/* Read one word from onboard paged RAM. */ +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; + 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)); + + return(ret); +} + + +/* Write one byte to onboard paged RAM. */ +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); + + /* Write the data. */ + *(uint8_t *)(dev->ems[vpage].addr + (addr - map->base)) = val; +} + + +/* Write one word to onboard paged RAM. */ +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); + + /* Write the data. */ + *(uint16_t *)(dev->ems[vpage].addr + (addr - map->base)) = val; +} + + +/* Handle a READ operation from one of our registers. */ +static uint8_t +ems_read(uint16_t port, void *priv) +{ + memdev_t *dev = (memdev_t *)priv; + uint8_t ret = 0xff; + int vpage; + + /* Get the viewport page number. */ + vpage = (port / EMS_PGSIZE); + + switch(port & 0x02ff) { + case 0x0208: /* page number register */ + case 0x0218: + case 0x0258: + case 0x0268: + case 0x02a8: + case 0x02b8: + case 0x02e8: + ret = dev->ems[vpage].page; + if (dev->ems[vpage].enabled) + ret |= 0x80; + break; + } + +#if 0 + pclog("ISAMEM: read(%04x) = %02x)\n", port, ret); +#endif + + return(ret); +} + + +/* Handle a WRITE operation to one of our registers. */ +static void +ems_write(uint16_t port, uint8_t val, void *priv) +{ + memdev_t *dev = (memdev_t *)priv; + int vpage; + + /* Get the viewport page number. */ + vpage = (port / EMS_PGSIZE); + +#if 0 + pclog("ISAMEM: write(%04x, %02x) page=%d\n", port, val, vpage); +#endif + + switch(port & 0x02ff) { + case 0x0208: /* page mapping registers */ + case 0x0218: + case 0x0258: + case 0x0268: + case 0x02a8: + case 0x02b8: + case 0x02e8: + /* Set the page number. */ + dev->ems[vpage].enabled = (val & 0x80); + dev->ems[vpage].page = (val & 0x7f); + + /* Make sure we can do that.. */ + if (dev->flags & FLAG_CONFIG) { + if (dev->ems[vpage].page < dev->ems_pages) { + /* Pre-calculate the page address in EMS RAM. */ + dev->ems[vpage].addr = dev->ram + dev->ems_start + ((val & 0x7f) * EMS_PGSIZE); + } else { + /* That page does not exist. */ + dev->ems[vpage].enabled = 0; + } + + if (dev->ems[vpage].enabled) { + /* Update the EMS RAM address for this page. */ + mem_mapping_set_exec(&dev->ems[vpage].mapping, + dev->ems[vpage].addr); + + /* Enable this page. */ + mem_mapping_enable(&dev->ems[vpage].mapping); + } else { + /* Disable this page. */ + mem_mapping_disable(&dev->ems[vpage].mapping); + } + } + break; + + case 0x0209: /* page frame registers */ + case 0x0219: + case 0x0259: + case 0x0269: + case 0x02a9: + case 0x02b9: + case 0x02e9: + /* + * The EV-159 EMM driver configures the frame address + * by setting bits in these registers. The information + * in their manual is unclear, but here is what was + * found out by repeatedly changing EMM's config: + * + * 00 04 08 Address + * ----------------- + * 80 c0 e0 E0000 + */ + + dev->ems[vpage].frame = val; + if (val) + dev->flags |= FLAG_CONFIG; + break; + } +} + + +/* Initialize the device for use. */ +static void * +isamem_init(const device_t *info) +{ + memdev_t *dev; + uint32_t k, t; + uint32_t addr; + uint32_t tot; + uint8_t *ptr; + int i; + + /* Find our device and create an instance. */ + for (i = 0; i < ISAMEM_MAX; i++) + if (instance[i] == info) break; + dev = (memdev_t *)malloc(sizeof(memdev_t)); + memset(dev, 0x00, sizeof(memdev_t)); + dev->name = info->name; + dev->board = info->local; + dev->instance = i; + + /* Do per-board initialization. */ + tot = 0; + switch(dev->board) { + case 0: /* IBM PC/XT Memory Expansion Card */ + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = dev->total_size; + break; + + case 1: /* IBM PC/AT Memory Expansion Card */ + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = dev->total_size; + dev->flags |= FLAG_WIDE; + break; + + case 10: /* Everex EV-159 RAM 3000 */ + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + tot = device_get_config_int("length"); + if (!!device_get_config_int("width")) + dev->flags |= FLAG_WIDE; + if (!!device_get_config_int("speed")) + dev->flags |= FLAG_FAST; + if (!!device_get_config_int("ems")) + dev->flags |= FLAG_EMS; +dev->frame_addr = 0xE0000; + break; + + case 11: + dev->base_addr = device_get_config_hex16("base"); + dev->total_size = device_get_config_int("size"); + dev->start_addr = device_get_config_int("start"); + dev->frame_addr = device_get_config_hex20("frame"); + if (!!device_get_config_int("width")) + dev->flags |= FLAG_WIDE; + if (!!device_get_config_int("speed")) + dev->flags |= FLAG_FAST; + break; + } + + /* Fix up the memory start address. */ + dev->start_addr <<= 10; + + /* Say hello! */ + pclog("ISAMEM: %s (%iKB", info->name, dev->total_size); + if (dev->total_size != tot) pclog(", %iKB for RAM", tot); + if (dev->flags & FLAG_FAST) pclog(", FAST"); + if (dev->flags & FLAG_WIDE) pclog(", 16BIT"); + pclog(")\n"); + + /* Force (back to) 8-bit bus if needed. */ + if (AT) { + if (! cpu_16bitbus) + pclog("ISAMEM: *WARNING* this board will slow down your PC!\n"); + } else { + pclog("ISAMEM: not AT+ system, forcing 8-bit mode!\n"); + dev->flags &= ~FLAG_WIDE; + } + + /* Allocate and initialize our RAM. */ + k = dev->total_size << 10; + dev->ram = (uint8_t *)malloc(k); + memset(dev->ram, 0x00, k); + ptr = dev->ram; + + /* + * The 'Memory Start Address' switch indicates at which address + * we should start adding memory. No memory is added if it is + * set to 0. + */ + tot <<= 10; + addr = dev->start_addr; + if (addr > 0 && tot > 0) { + /* Adjust K for the RAM we will use. */ + k -= tot; + + /* + * First, see if we have to expand the conventional + * (low) memory area. This can extend up to 640KB, + * so check this first. + */ + t = (addr < RAM_TOPMEM) ? RAM_TOPMEM - addr : 0; + if (t > 0) { + /* + * We need T bytes to extend that area. + * + * If the board doesn't have that much, grab + * as much as we can. + */ + if (t > tot) + t = tot; + pclog("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); + + /* Create, initialize and enable the low-memory mapping. */ + mem_mapping_add(&dev->low_mapping, addr, t, + ram_readb, + (dev->flags&FLAG_WIDE) ? ram_readw : NULL, + NULL, + 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); + + /* Tell the memory system this is external RAM. */ + mem_set_mem_state(addr, t, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + /* Update pointers. */ + ptr += t; + tot -= t; + addr += t; + } + + /* Skip to high memory if needed. */ + if ((addr == RAM_TOPMEM) && (tot >= RAM_UMAMEM)) { + /* + * We have more RAM available, but we are at the + * top of conventional RAM. So, the next 384K are + * skipped, and placed into different mappings so + * they can be re-mapped later. + */ + t = RAM_UMAMEM; /* 384KB */ + + pclog("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); + + /* Update and enable the remap. */ + mem_mapping_del(&ram_remapped_mapping); + mem_mapping_add(&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); + mem_mapping_disable(&ram_remapped_mapping); + + /* Tell the memory system this is external RAM. */ + mem_set_mem_state(addr + tot, t, + MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + /* Update pointers. */ + ptr += t; + tot -= t; + addr += t; + } + } + + /* + * Next, on systems that support it (80286 and up), we can add + * (some of) our RAM to the system as Extended Memory, that is, + * memory located above 1MB. This memory cannot be addressed in + * real mode (so, not by DOS, for example) but it can be used in + * protected mode. + */ + if (AT && addr > 0 && tot > 0) { + t = tot; + pclog("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); + + /* 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); + + /* Tell the memory system this is external RAM. */ + mem_set_mem_state(addr, t, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + /* Update pointers. */ + ptr += t; + tot -= t; + addr += t; + } + + /* If EMS is enabled, use the remainder for EMS. */ + if (dev->flags & FLAG_EMS) { + /* EMS 3.2 cannot have more than 2048KB per board. */ + t = k; + if (t > EMS_MAXSIZE) + t = EMS_MAXSIZE; + + /* Set up where EMS begins in local RAM, and how much we have. */ + dev->ems_start = ptr - dev->ram; + dev->ems_size = t >> 10; + dev->ems_pages = t / EMS_PGSIZE; + pclog("ISAMEM: EMS enabled, I/O=%04xH, %iKB (%i pages)", + dev->base_addr, dev->ems_size, dev->ems_pages); + if (dev->frame_addr > 0) + pclog(", Frame=%05XH", dev->frame_addr); + pclog("\n"); + + /* + * For each supported page (we can have a maximum of 4), + * create, initialize and disable the mappings, and set + * up the I/O control handler. + */ + for (i = 0; i < EMS_MAXPAGE; i++) { + /* Create and initialize a page mapping. */ + mem_mapping_add(&dev->ems[i].mapping, + dev->frame_addr + (EMS_PGSIZE*i), EMS_PGSIZE, + ems_readb, + (dev->flags&FLAG_WIDE) ? ems_readw : NULL, + NULL, + ems_writeb, + (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); + + /* For now, disable it. */ + mem_mapping_disable(&dev->ems[i].mapping); + + /* Set up an I/O port handler. */ + io_sethandler(dev->base_addr + (EMS_PGSIZE*i), 2, + ems_read,NULL,NULL, ems_write,NULL,NULL, dev); + } + } + + /* Just so its not NULL. */ + return((void *)dev); +} + + +/* Remove the device from the system. */ +static void +isamem_close(void *priv) +{ + memdev_t *dev = (memdev_t *)priv; + int i; + + if (dev->flags & FLAG_EMS) { + for (i = 0; i < EMS_MAXPAGE; i++) { + io_removehandler(dev->base_addr + (EMS_PGSIZE*i), 2, + ems_read,NULL,NULL, ems_write,NULL,NULL, dev); + + } + } + + if (dev->ram != NULL) + free(dev->ram); + + instance[dev->instance] = NULL; + + free(dev); +} + + +static const device_config_t ibmxt_config[] = +{ + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, + { { 0 } }, + { { 0 } }, + { 0, 256, 16 } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 256, + { { 0 } }, + { { 0 } }, + { 0, 640-64, 64 } + }, + { + "", "", -1 + } +}; + +static const device_t ibmxt_device = { + "IBM PC/XT Memory Expansion", + DEVICE_ISA, + 0, + isamem_init, isamem_close, NULL, + NULL, NULL, NULL, NULL, + ibmxt_config +}; + + +static const device_config_t ibmat_config[] = +{ + { + "size", "Memory Size", CONFIG_SPINNER, "", 512, + { { 0 } }, + { { 0 } }, + { 0, 4096, 512 } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 512, + { { 0 } }, + { { 0 } }, + { 0, 16128, 128 } + }, + { + "", "", -1 + } +}; + +static const device_t ibmat_device = { + "IBM PC/AT Memory Expansion", + DEVICE_ISA, + 1, + isamem_init, isamem_close, NULL, + NULL, NULL, NULL, NULL, + ibmat_config +}; + + +static const device_config_t ev159_config[] = +{ + { + "size", "Memory Size", CONFIG_SPINNER, "", 512, + { { 0 } }, + { { 0 } }, + { 0, 3072, 512 } + }, + { + "start", "Start Address", CONFIG_SPINNER, "", 0, + { { 0 } }, + { { 0 } }, + { 0, 16128, 128 } + }, + { + "length", "Contiguous Size", CONFIG_SPINNER, "", 0, + { { 0 } }, + { { 0 } }, + { 0, 16384, 128 } + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 0, + { + { + "8-bit", 0 + }, + { + "16-bit", 1 + }, + { + "" + } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, + { + { + "Standard (150ns)", 0 + }, + { + "High-Speed (120ns)", 1 + }, + { + "" + } + } + }, + { + "ems", "EMS mode", CONFIG_SELECTION, "", 0, + { + { + "Disabled", 0 + }, + { + "Enabled", 1 + }, + { + "" + } + }, + }, + { + "base", "Address", CONFIG_HEX16, "", 0x0258, + { + { + "208H", 0x0208 + }, + { + "218H", 0x0218 + }, + { + "258H", 0x0258 + }, + { + "268H", 0x0268 + }, + { + "2A8H", 0x02A8 + }, + { + "2B8H", 0x02B8 + }, + { + "2E8H", 0x02E8 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + +static const device_t ev159_device = { + "Everex EV-159 RAM 3000 Deluxe", + DEVICE_ISA, + 10, + isamem_init, isamem_close, NULL, + NULL, NULL, NULL, NULL, + ev159_config +}; + + +#ifdef USE_ISAMEM_RAMPAGE +static const device_config_t rampage_config[] = +{ + { + "base", "Address", CONFIG_HEX16, "", 0x0258, + { + { + "208H", 0x0208 + }, + { + "218H", 0x0218 + }, + { + "258H", 0x0258 + }, + { + "268H", 0x0268 + }, + { + "2A8H", 0x02A8 + }, + { + "2B8H", 0x02B8 + }, + { + "2E8H", 0x02E8 + }, + { + "" + } + }, + }, + { + "frame", "Frame Address", CONFIG_HEX20, "", 0, + { + { + "Disabled", 0x00000 + }, + { + "C000H", 0xC0000 + }, + { + "D000H", 0xD0000 + }, + { + "E000H", 0xE0000 + }, + { + "" + } + }, + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 8, + { + { + "8-bit", 8 + }, + { + "16-bit", 16 + }, + { + "" + } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, + { + { + "Standard", 0 + }, + { + "High-Speed", 1 + }, + { + "" + } + } + }, + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, + { { 0 } }, + { { 0 } }, + { 0, 8192, 128 } + }, + { + "", "", -1 + } +}; + +static const device_t isamem_rampage_device = { + "AST RAMpage/XT", + DEVICE_ISA, + 11, + isamem_init, isamem_close, NULL, + NULL, NULL, NULL, NULL, + rampage_config +}; +#endif + + +static const struct { + const char *internal_name; + const device_t *dev; +} boards[] = { + { "none", NULL, }, + { "ibmxt", &ibmxt_device, }, + { "ibmat", &ibmat_device, }, + { "ev159", &ev159_device, }, +#ifdef USE_ISAMEM_BRAT + { "brat", &brat_device, }, +#endif +#ifdef USE_ISAMEM_RAMPAGE + { "rampage", &rampage_device, }, +#endif +#ifdef USE_ISAMEM_IAB + { "iab", &iab_device, }, +#endif + { NULL, NULL } +}; + + +void +isamem_reset(void) +{ + const device_t *dev; + int k, i; + + for (i = 0; i < ISAMEM_MAX; i++) { + k = isamem_type[i]; + if (k == 0) continue; + + /* Clone the device. */ + dev = device_clone(boards[k].dev); + + /* Store the device instance. */ + instance[i] = dev; + + /* Add the instance to the system. */ + device_add(dev); + } +} + + +const char * +isamem_get_name(int board) +{ + if (boards[board].dev == NULL) return(NULL); + + return(boards[board].dev->name); +} + + +const char * +isamem_get_internal_name(int board) +{ + return(boards[board].internal_name); +} + + + +int +isamem_get_from_internal_name(const char *s) +{ + int c = 0; + + while (boards[c].internal_name != NULL) { + if (! strcmp(boards[c].internal_name, s)) + return(c); + c++; + } + + /* Not found. */ + return(0); +} + + +const device_t * +isamem_get_device(int board) +{ + return(instance[board]); +} diff --git a/src/devices/misc/isamem.h b/src/devices/misc/isamem.h new file mode 100644 index 0000000..a612df5 --- /dev/null +++ b/src/devices/misc/isamem.h @@ -0,0 +1,77 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the ISAMEM cards. + * + * Version: @(#)isamem.h 1.0.1 2018/08/18 + * + * Authors: Fred N. van Kempen, + * + * Copyright 2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef ISAMEM_H +# define ISAMEM_H + + +#define ISAMEM_MAX 4 /* max #cards in system */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables. */ +extern const device_t isamem_device; +extern const device_t isamem_brat80_device; +extern const device_t isamem_ev159_device; + + +/* Functions. */ +extern void isamem_reset(void); + +extern const char *isamem_get_name(int t); +extern const char *isamem_get_internal_name(int t); +extern int isamem_get_from_internal_name(const char *s); +extern const device_t *isamem_get_device(int t); + +#ifdef __cplusplus +} +#endif + + +#endif /*ISAMEM_H*/ diff --git a/src/emu.h b/src/emu.h index d8aaa85..7d43005 100644 --- a/src/emu.h +++ b/src/emu.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)emu.h 1.0.26 2018/06/25 + * Version: @(#)emu.h 1.0.27 2018/08/18 * * Author: Fred N. van Kempen, * @@ -123,7 +123,8 @@ extern int game_enabled, /* (C) enable game port */ serial_enabled[], /* (C) enable serial ports */ parallel_enabled[], /* (C) enable LPT ports */ parallel_device[], /* (C) set up LPT devices */ - bugger_enabled; /* (C) enable ISAbugger */ + bugger_enabled, /* (C) enable ISAbugger */ + isamem_type[]; /* (C) enable ISA mem cards */ #ifdef WALTJE extern int romdos_enabled; /* (C) enable ROM DOS */ #endif diff --git a/src/pc.c b/src/pc.c index a356ce4..910e72c 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.49 2018/07/28 + * Version: @(#)pc.c 1.0.50 2018/08/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -85,6 +85,7 @@ #include "devices/sound/snd_speaker.h" #include "devices/video/video.h" #include "devices/misc/bugger.h" +#include "devices/misc/isamem.h" #include "ui/ui.h" #include "plat.h" @@ -135,7 +136,8 @@ int game_enabled = 0, /* (C) enable game port */ serial_enabled[] = {0,0}, /* (C) enable serial ports */ parallel_enabled[] = {0,0,0}, /* (C) enable LPT ports */ parallel_device[] = {0,0,0}, /* (C) set up LPT devices */ - bugger_enabled = 0; /* (C) enable ISAbugger */ + bugger_enabled = 0, /* (C) enable ISAbugger */ + isamem_type[ISAMEM_MAX] = { 0,0,0,0 }; /* (C) enable ISA mem cards */ #ifdef WALTJE int romdos_enabled = 0; /* (C) enable ROM DOS */ #endif @@ -991,6 +993,9 @@ pc_reset_hard_init(void) /* FIXME: move elsewhere? */ shadowbios = 0; + /* Reset any ISA memory cards. */ + isamem_reset(); + fdd_reset(); /* diff --git a/src/win/VARCem-common.rc b/src/win/VARCem-common.rc index e43ea95..d26812d 100644 --- a/src/win/VARCem-common.rc +++ b/src/win/VARCem-common.rc @@ -8,7 +8,7 @@ * * Common resources for the application. * - * Version: @(#)VARCem-common.rc 1.0.6 2018/06/06 + * Version: @(#)VARCem-common.rc 1.0.7 2018/08/18 * * Author: Fred N. van Kempen, * @@ -423,7 +423,7 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,7,107,110,10 END -DLG_CFG_PERIPHERALS DIALOG 97, 0, 267, 97 +DLG_CFG_PERIPHERALS DIALOG 97, 0, 267, 180 STYLE DS_CONTROL | WS_CHILD FONT 9, FONT_NAME BEGIN @@ -447,6 +447,24 @@ BEGIN CONTROL STR_3479,IDC_CHECK_BUGGER,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + + GROUPBOX "ISA Memory Expansion",IDC_GROUP_ISAMEM,7,99,255,70 + LTEXT "#1:",IDT_1763,12,111,21,10 + COMBOBOX IDC_COMBO_ISAMEM_1,25,110,180,120, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON STR_CONFIGURE,IDC_CONFIGURE_ISAMEM_1,209,110,46,12 + LTEXT "#2:",IDT_1764,12,125,21,10 + COMBOBOX IDC_COMBO_ISAMEM_2,25,124,180,120, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON STR_CONFIGURE,IDC_CONFIGURE_ISAMEM_2,209,124,46,12 + LTEXT "#3:",IDT_1765,12,139,21,10 + COMBOBOX IDC_COMBO_ISAMEM_3,25,138,180,120, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON STR_CONFIGURE,IDC_CONFIGURE_ISAMEM_3,209,138,46,12 + LTEXT "#4:",IDT_1766,12,153,21,10 + COMBOBOX IDC_COMBO_ISAMEM_4,25,152,180,120, + CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON STR_CONFIGURE,IDC_CONFIGURE_ISAMEM_4,209,152,46,12 END DLG_CFG_DISK DIALOG 97, 0, 267, 154 diff --git a/src/win/mingw/Makefile.MinGW b/src/win/mingw/Makefile.MinGW index c887246..987f111 100644 --- a/src/win/mingw/Makefile.MinGW +++ b/src/win/mingw/Makefile.MinGW @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the MinGW32 environment. # -# Version: @(#)Makefile.mingw 1.0.50 2018/07/28 +# Version: @(#)Makefile.mingw 1.0.51 2018/08/14 # # Author: Fred N. van Kempen, # @@ -603,6 +603,7 @@ INTELOBJ := intel.o \ intel_piix.o intel_piix4.o DEVOBJ := bugger.o \ + isamem.o \ game.o game_dev.o \ parallel.o parallel_dev.o serial.o \ sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \ diff --git a/src/win/msvc/Makefile.VC b/src/win/msvc/Makefile.VC index abca1a2..97c89a9 100644 --- a/src/win/msvc/Makefile.VC +++ b/src/win/msvc/Makefile.VC @@ -8,7 +8,7 @@ # # Makefile for Windows using Visual Studio 2015. # -# Version: @(#)Makefile.VC 1.0.37 2018/07/28 +# Version: @(#)Makefile.VC 1.0.38 2018/08/12 # # Author: Fred N. van Kempen, # @@ -573,6 +573,7 @@ INTELOBJ := intel.obj \ intel_piix.obj intel_piix4.obj DEVOBJ := bugger.obj \ + isamem.obj \ game.obj game_dev.obj \ parallel.obj parallel_dev.obj serial.obj \ sio_fdc37c66x.obj sio_fdc37c669.obj sio_fdc37c93x.obj \ diff --git a/src/win/resource.h b/src/win/resource.h index b26b190..2426d93 100644 --- a/src/win/resource.h +++ b/src/win/resource.h @@ -8,7 +8,7 @@ * * Windows resource defines. * - * Version: @(#)resource.h 1.0.16 2018/05/28 + * Version: @(#)resource.h 1.0.17 2018/08/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -113,6 +113,10 @@ #define IDT_1758 1758 /* ZIP drives: */ #define IDT_1761 1761 /* Speed: */ #define IDT_1762 1762 /* ZIP drives: */ +#define IDT_1763 1763 /* Board #1: */ +#define IDT_1764 1764 /* Board #2: */ +#define IDT_1765 1765 /* Board #3: */ +#define IDT_1766 1766 /* Board #4: */ #define IDT_TITLE 1790 /* "VARCem for Plaform" */ #define IDT_VERSION 1791 /* "version.." */ @@ -183,49 +187,60 @@ #define IDC_COMBO_IDE_TER 1125 #define IDC_COMBO_IDE_QUA 1126 #define IDC_CHECK_BUGGER 1127 +#define IDC_CONFIGURE_BUGGER 1128 -#define IDC_HARD_DISKS 1130 /* hard disk config */ -#define IDC_LIST_HARD_DISKS 1131 -#define IDC_BUTTON_HDD_ADD_NEW 1132 -#define IDC_BUTTON_HDD_ADD 1133 -#define IDC_BUTTON_HDD_REMOVE 1134 -#define IDC_COMBO_HD_BUS 1135 -#define IDC_COMBO_HD_CHANNEL 1136 -#define IDC_COMBO_HD_ID 1137 -#define IDC_COMBO_HD_LUN 1138 -#define IDC_COMBO_HD_CHANNEL_IDE 1139 +#define IDC_GROUP_ISAMEM 1140 +#define IDC_COMBO_ISAMEM_1 1141 +#define IDC_COMBO_ISAMEM_2 1142 +#define IDC_COMBO_ISAMEM_3 1143 +#define IDC_COMBO_ISAMEM_4 1144 +#define IDC_CONFIGURE_ISAMEM_1 1145 +#define IDC_CONFIGURE_ISAMEM_2 1146 +#define IDC_CONFIGURE_ISAMEM_3 1147 +#define IDC_CONFIGURE_ISAMEM_4 1148 -#define IDC_EDIT_HD_FILE_NAME 1140 /* add hard disk dialog */ -#define IDC_EDIT_HD_SPT 1141 -#define IDC_EDIT_HD_HPC 1142 -#define IDC_EDIT_HD_CYL 1143 -#define IDC_EDIT_HD_SIZE 1144 -#define IDC_COMBO_HD_TYPE 1145 -#define IDC_PBAR_IMG_CREATE 1146 +#define IDC_HARD_DISKS 1150 /* hard disk config */ +#define IDC_LIST_HARD_DISKS 1151 +#define IDC_BUTTON_HDD_ADD_NEW 1152 +#define IDC_BUTTON_HDD_ADD 1153 +#define IDC_BUTTON_HDD_REMOVE 1154 +#define IDC_COMBO_HD_BUS 1155 +#define IDC_COMBO_HD_CHANNEL 1156 +#define IDC_COMBO_HD_ID 1157 +#define IDC_COMBO_HD_LUN 1158 +#define IDC_COMBO_HD_CHANNEL_IDE 1159 -#define IDC_REMOV_DEVICES 1150 /* removable dev config */ -#define IDC_LIST_FLOPPY_DRIVES 1151 -#define IDC_COMBO_FD_TYPE 1152 -#define IDC_CHECKTURBO 1153 -#define IDC_CHECKBPB 1154 -#define IDC_LIST_CDROM_DRIVES 1155 -#define IDC_COMBO_CD_BUS 1156 -#define IDC_COMBO_CD_ID 1157 -#define IDC_COMBO_CD_LUN 1158 -#define IDC_COMBO_CD_CHANNEL_IDE 1159 -#define IDC_LIST_ZIP_DRIVES 1160 -#define IDC_COMBO_ZIP_BUS 1161 -#define IDC_COMBO_ZIP_ID 1162 -#define IDC_COMBO_ZIP_LUN 1163 -#define IDC_COMBO_ZIP_CHANNEL_IDE 1164 -#define IDC_CHECK250 1165 -#define IDC_COMBO_CD_SPEED 1166 +#define IDC_EDIT_HD_FILE_NAME 1160 /* add hard disk dialog */ +#define IDC_EDIT_HD_SPT 1161 +#define IDC_EDIT_HD_HPC 1162 +#define IDC_EDIT_HD_CYL 1163 +#define IDC_EDIT_HD_SIZE 1164 +#define IDC_COMBO_HD_TYPE 1165 +#define IDC_PBAR_IMG_CREATE 1166 -#define IDC_SLIDER_GAIN 1180 /* sound gain dialog */ +#define IDC_REMOV_DEVICES 1170 /* removable dev config */ +#define IDC_LIST_FLOPPY_DRIVES 1171 +#define IDC_COMBO_FD_TYPE 1172 +#define IDC_CHECKTURBO 1173 +#define IDC_CHECKBPB 1174 +#define IDC_LIST_CDROM_DRIVES 1175 +#define IDC_COMBO_CD_BUS 1176 +#define IDC_COMBO_CD_ID 1177 +#define IDC_COMBO_CD_LUN 1178 +#define IDC_COMBO_CD_CHANNEL_IDE 1179 +#define IDC_LIST_ZIP_DRIVES 1180 +#define IDC_COMBO_ZIP_BUS 1181 +#define IDC_COMBO_ZIP_ID 1182 +#define IDC_COMBO_ZIP_LUN 1183 +#define IDC_COMBO_ZIP_CHANNEL_IDE 1184 +#define IDC_CHECK250 1185 +#define IDC_COMBO_CD_SPEED 1186 -#define IDC_EDIT_FILE_NAME 1190 /* new floppy image dialog */ -#define IDC_COMBO_DISK_SIZE 1191 -#define IDC_COMBO_RPM_MODE 1192 +#define IDC_SLIDER_GAIN 1190 /* sound gain dialog */ + +#define IDC_EDIT_FILE_NAME 1195 /* new floppy image dialog */ +#define IDC_COMBO_DISK_SIZE 1196 +#define IDC_COMBO_RPM_MODE 1197 /* For the DeviceConfig code, re-do later. */ diff --git a/src/win/win_settings.c b/src/win/win_settings.c index ca050de..ab32224 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings.c 1.0.31 2018/05/24 + * Version: @(#)win_settings.c 1.0.32 2018/08/18 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -58,6 +58,7 @@ #include "../devices/ports/parallel.h" #include "../devices/ports/parallel_dev.h" #include "../devices/ports/serial.h" +#include "../devices/misc/isamem.h" #include "../devices/input/mouse.h" #include "../devices/input/game/joystick.h" #include "../devices/floppy/fdd.h" @@ -112,7 +113,8 @@ static int temp_hdc_type, temp_scsi_card, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; -static int temp_bugger; +static int temp_bugger, + temp_isamem[ISAMEM_MAX]; /* Floppy drives category. */ static int temp_fdd_types[FDD_NUM], @@ -169,7 +171,7 @@ settings_msgbox(int type, void *arg) static void settings_init(void) { - int i = 0; + int i; /* Machine category */ temp_machine = machine; @@ -223,8 +225,12 @@ settings_init(void) temp_ide_qua_irq = ide_irq[3]; temp_bugger = bugger_enabled; + /* ISA memory boards. */ + for (i = 0; i < ISAMEM_MAX; i++) + temp_isamem[i] = isamem_type[i]; + /* Floppy drives category */ - for (i=0; i * Miran Grca, @@ -210,6 +210,38 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); SendMessage(h, BM_SETCHECK, temp_bugger, 0); + /* Populate the ISA memory card dropdowns. */ + for (c = 0; c < ISAMEM_MAX; c++) { + h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_1 + c); + + d = 0; + for (;;) { + stransi = isamem_get_internal_name(d); + if (stransi == NULL) + break; + + if (d == 0) { + /* Translate "None". */ + SendMessage(h, CB_ADDSTRING, 0, + (LPARAM)get_string(IDS_NONE)); + } else { + stransi = isamem_get_name(d); + mbstowcs(temp, stransi, sizeof_w(temp)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)temp); + } + + d++; + } + + SendMessage(h, CB_SETCURSEL, temp_isamem[c], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_ISAMEM_1 + c); + if (temp_isamem[c] != 0) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + } + return TRUE; case WM_COMMAND: @@ -249,6 +281,29 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) else EnableWindow(h, FALSE); break; + + case IDC_COMBO_ISAMEM_1: + case IDC_COMBO_ISAMEM_2: + case IDC_COMBO_ISAMEM_3: + case IDC_COMBO_ISAMEM_4: + c = LOWORD(wParam) - IDC_COMBO_ISAMEM_1; + h = GetDlgItem(hdlg, LOWORD(wParam)); + temp_isamem[c] = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_ISAMEM_1 + c); + if (temp_isamem[c] != 0) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + break; + + case IDC_CONFIGURE_ISAMEM_1: + case IDC_CONFIGURE_ISAMEM_2: + case IDC_CONFIGURE_ISAMEM_3: + case IDC_CONFIGURE_ISAMEM_4: + c = LOWORD(wParam) - IDC_CONFIGURE_ISAMEM_1; + temp_deviceconfig |= dlg_devconf(hdlg, (void *)isamem_get_device(c)); + break; } return FALSE; @@ -279,6 +334,7 @@ peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + return FALSE; default: