Ported the ISA RTC and Memory expansion cards from VARCem's.

Bunch of improvements in the device, memory and MMU handling.
Re-worked the NEAT 286 chipset (ported from VARCem).
Re-worked the ATI 28800 a bit, added Sierra SC1502x ramdac to VGA Wonder XL (Compaq) since it supports such.
Top 384K memory handling improvements (256K top memory too)
Added MCA version of MPU-401 (not tested much, however).
Re-worked the SCAT 286 chipset.
This commit is contained in:
TC1995
2018-09-03 13:55:09 +02:00
parent 0e96d5d7a4
commit 0d2ee0a57d
29 changed files with 3605 additions and 422 deletions

View File

@@ -93,7 +93,9 @@ extern int vid_cga_contrast, /* (C) video */
gfxcard; /* (C) graphics/video card */ gfxcard; /* (C) graphics/video card */
extern int serial_enabled[], /* (C) enable serial ports */ extern int serial_enabled[], /* (C) enable serial ports */
lpt_enabled, /* (C) enable LPT ports */ lpt_enabled, /* (C) enable LPT ports */
bugger_enabled; /* (C) enable ISAbugger */ bugger_enabled, /* (C) enable ISAbugger */
isamem_type[], /* (C) enable ISA mem cards */
isartc_type; /* (C) enable ISA RTC card */
extern int sound_is_float, /* (C) sound uses FP values */ extern int sound_is_float, /* (C) sound uses FP values */
GAMEBLASTER, /* (C) sound option */ GAMEBLASTER, /* (C) sound option */
GUS, /* (C) sound option */ GUS, /* (C) sound option */

View File

@@ -1,4 +1,4 @@
/* /*
* VARCem Virtual ARchaeological Computer EMulator. * VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices, * An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly * using the ISA,EISA,VLB,MCA and PCI system buses, roughly

View File

@@ -9,7 +9,7 @@
* Implementation of the generic device interface to handle * Implementation of the generic device interface to handle
* all devices attached to the emulator. * all devices attached to the emulator.
* *
* Version: @(#)device.c 1.0.8 2018/04/29 * Version: @(#)device.c 1.0.9 2018/09/02
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -39,6 +39,7 @@
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
@@ -54,9 +55,17 @@
#define DEVICE_MAX 256 /* max # of devices */ #define DEVICE_MAX 256 /* max # of devices */
static void *device_priv[DEVICE_MAX]; typedef struct clonedev {
static device_t *devices[DEVICE_MAX]; const device_t *master;
static device_t *device_current; int count;
struct clonedev *next;
} clonedev_t;
static device_t *devices[DEVICE_MAX];
static void *device_priv[DEVICE_MAX];
static device_t *device_current;
static clonedev_t *clones;
#ifdef ENABLE_DEVICE_LOG #ifdef ENABLE_DEVICE_LOG
@@ -78,7 +87,7 @@ device_log(const char *format, ...)
#endif #endif
} }
/* Initialize the module for use. */
void void
device_init(void) device_init(void)
{ {
@@ -86,6 +95,50 @@ device_init(void)
} }
/* Clone a master device for multi-instance devices. */
const device_t *
device_clone(const device_t *master)
{
char temp[1024], *sp;
clonedev_t *cl, *ptr;
device_t *dev;
/* Look up the master. */
for (ptr = clones; ptr != NULL; ptr = ptr->next)
if (ptr->master == master) break;
/* If not found, add this master to the list. */
if (ptr == NULL) {
ptr = (clonedev_t *)malloc(sizeof(clonedev_t));
memset(ptr, 0x00, sizeof(clonedev_t));
if (clones != NULL) {
for (cl = clones; cl->next != NULL; cl = cl->next)
;
cl->next = ptr;
} else
clones = ptr;
ptr->master = master;
}
/* Create a new device. */
dev = (device_t *)malloc(sizeof(device_t));
/* Copy the master info. */
memcpy(dev, ptr->master, sizeof(device_t));
/* Set up a clone. */
if (++ptr->count > 1)
sprintf(temp, "%s #%i", ptr->master->name, ptr->count);
else
strcpy(temp, ptr->master->name);
sp = (char *)malloc(strlen(temp) + 1);
strcpy(sp, temp);
dev->name = (const char *)sp;
return((const device_t *)dev);
}
void * void *
device_add(const device_t *d) device_add(const device_t *d)
{ {

View File

@@ -8,7 +8,7 @@
* *
* Definitions for the device handler. * Definitions for the device handler.
* *
* Version: @(#)device.h 1.0.5 2018/04/26 * Version: @(#)device.h 1.0.6 2018/09/02
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -114,6 +114,7 @@ extern "C" {
#endif #endif
extern void device_init(void); extern void device_init(void);
extern const device_t * device_clone(const device_t *master);
extern void *device_add(const device_t *d); extern void *device_add(const device_t *d);
extern void device_add_ex(const device_t *d, void *priv); extern void device_add_ex(const device_t *d, void *priv);
extern void device_close_all(void); extern void device_close_all(void);

971
src/isamem.c Normal file
View File

@@ -0,0 +1,971 @@
/*
* 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, <decwiz@yahoo.com>
*
* 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 <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "86box.h"
#include "cpu/cpu.h"
#include "machine/machine.h"
#include "io.h"
#include "mem.h"
#include "device.h"
#include "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;
/* 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. */
dev = (memdev_t *)malloc(sizeof(memdev_t));
memset(dev, 0x00, sizeof(memdev_t));
dev->name = info->name;
dev->board = info->local;
/* 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);
if (dev != 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,
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,
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,
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,
rampage_config
};
#endif
static const struct {
const char *name;
const char *internal_name;
const device_t *dev;
} boards[] = {
{ "None", "none", NULL, },
{ "IBM PC/XT Memory Expansion", "ibmxt", &ibmxt_device, },
{ "IBM PC/AT Memory Expansion", "ibmat", &ibmat_device, },
{ "Everex EV-159 RAM 3000 Deluxe", "ev159", &ev159_device, },
{ "", "", 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);
/* Add the instance to the system. */
device_add(dev);
}
}
char *
isamem_get_name(int board)
{
return((char *)boards[board].name);
}
char *
isamem_get_internal_name(int board)
{
return((char *)boards[board].internal_name);
}
int
isamem_get_from_internal_name(char *s)
{
int c = 0;
while (strlen((char *) boards[c].internal_name)) {
if (!strcmp((char *)boards[c].internal_name, s))
return(c);
c++;
}
/* Not found. */
return(0);
}
const device_t *
isamem_get_device(int board)
{
return(boards[board].dev);
}

77
src/isamem.h Normal file
View File

@@ -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, <decwiz@yahoo.com>
*
* 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 char *isamem_get_name(int t);
extern char *isamem_get_internal_name(int t);
extern int isamem_get_from_internal_name(char *s);
extern const device_t *isamem_get_device(int t);
#ifdef __cplusplus
}
#endif
#endif /*ISAMEM_H*/

739
src/isartc.c Normal file
View File

@@ -0,0 +1,739 @@
/*
* 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 Clock/RTC Card for the ISA PC/XT.
*
* Systems starting with the PC/XT had, by default, a realtime
* clock and NVR chip on the mainboard. The BIOS stored config
* data in the NVR, and the system could maintain time and date
* using the RTC.
*
* Originally, PC systems did not have this, and they first did
* show up in non-IBM clone systems. Shortly after, expansion
* cards with this function became available for the PC's (ISA)
* bus, and they came in many forms and designs.
*
* This implementation offers some of those boards:
*
* Everex EV-170 (using NatSemi MM58167 chip)
* DTK PII-147 Hexa I/O Plus (using UMC 82C8167 chip)
*
* and more will follow as time permits.
*
* NOTE: The IRQ functionalities have been implemented, but not yet
* tested, as I need to write test software for them first :)
*
* Version: @(#)isartc.c 1.0.4 2018/08/31
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
* 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 <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include "86box.h"
#include "cpu/cpu.h"
#include "machine/machine.h"
#include "io.h"
#include "device.h"
#include "nvr.h"
#include "ui.h"
#include "plat.h"
#include "pic.h"
#include "isartc.h"
#define ISARTC_DEBUG 0
typedef struct {
const char *name; /* board name */
uint8_t board; /* board type */
uint8_t flags; /* various flags */
#define FLAG_YEAR80 0x01 /* YEAR byte is base-80 */
#define FLAG_YEARBCD 0x02 /* YEAR byte is in BCD */
int8_t irq; /* configured IRQ channel */
int8_t base_addrsz;
uint32_t base_addr; /* configured I/O address */
/* Fields for the specific driver. */
void (*f_wr)(uint16_t, uint8_t, void *);
uint8_t (*f_rd)(uint16_t, void *);
int8_t year; /* register for YEAR value */
char pad[3];
nvr_t nvr; /* RTC/NVR */
} rtcdev_t;
/************************************************************************
* *
* Driver for the NatSemi MM58167 chip. *
* *
************************************************************************/
#define MM67_REGS 32
/* Define the RTC chip registers - see datasheet, pg4. */
#define MM67_MSEC 0 /* milliseconds */
#define MM67_HUNTEN 1 /* hundredths/tenths of seconds */
#define MM67_SEC 2 /* seconds */
#define MM67_MIN 3 /* minutes */
#define MM67_HOUR 4 /* hours */
#define MM67_DOW 5 /* day of the week */
#define MM67_DOM 6 /* day of the month */
#define MM67_MON 7 /* month */
#define MM67_AL_MSEC 8 /* milliseconds */
#define MM67_AL_HUNTEN 9 /* hundredths/tenths of seconds */
#define MM67_AL_SEC 10 /* seconds */
#define MM67_AL_MIN 11 /* minutes */
#define MM67_AL_HOUR 12 /* hours */
#define MM67_AL_DOW 13 /* day of the week */
#define MM67_AL_DOM 14 /* day of the month */
#define MM67_AL_MON 15 /* month */
# define MM67_AL_DONTCARE 0xc0 /* always match in compare */
#define MM67_ISTAT 16 /* IRQ status */
#define MM67_ICTRL 17 /* IRQ control */
# define MM67INT_COMPARE 0x01 /* Compare */
# define MM67INT_TENTH 0x02 /* Tenth */
# define MM67INT_SEC 0x04 /* Second */
# define MM67INT_MIN 0x08 /* Minute */
# define MM67INT_HOUR 0x10 /* Hour */
# define MM67INT_DAY 0x20 /* Day */
# define MM67INT_WEEK 0x40 /* Week */
# define MM67INT_MON 0x80 /* Month */
#define MM67_RSTCTR 18 /* reset counters */
#define MM67_RSTRAM 19 /* reset RAM */
#define MM67_STATUS 20 /* status bit */
#define MM67_GOCMD 21 /* GO Command */
#define MM67_STBYIRQ 22 /* standby IRQ */
#define MM67_TEST 31 /* test mode */
/* Check if the current time matches a set alarm time. */
static int8_t
mm67_chkalrm(nvr_t *nvr, int8_t addr)
{
return((nvr->regs[addr-MM67_AL_SEC+MM67_SEC] == nvr->regs[addr]) ||
((nvr->regs[addr] & MM67_AL_DONTCARE) == MM67_AL_DONTCARE));
}
/*
* This is called every second through the NVR/RTC hook.
*
* We fake a 'running' RTC by updating its registers on
* each passing second. Not exactly accurate, but good
* enough.
*
* Note that this code looks nasty because of all the
* BCD to decimal vv going on.
*/
static void
mm67_tick(nvr_t *nvr)
{
rtcdev_t *dev = (rtcdev_t *)nvr->data;
uint8_t *regs = nvr->regs;
int mon, year, f = 0;
/* Update and set interrupt if needed. */
regs[MM67_SEC] = RTC_BCDINC(nvr->regs[MM67_SEC], 1);
if (regs[MM67_ICTRL] & MM67INT_SEC) f = MM67INT_SEC;
/* Roll over? */
if (regs[MM67_SEC] >= RTC_BCD(60)) {
/* Update and set interrupt if needed. */
regs[MM67_SEC] = RTC_BCD(0);
regs[MM67_MIN] = RTC_BCDINC(regs[MM67_MIN], 1);
if (regs[MM67_ICTRL] & MM67INT_MIN) f = MM67INT_MIN;
/* Roll over? */
if (regs[MM67_MIN] >= RTC_BCD(60)) {
/* Update and set interrupt if needed. */
regs[MM67_MIN] = RTC_BCD(0);
regs[MM67_HOUR] = RTC_BCDINC(regs[MM67_HOUR], 1);
if (regs[MM67_ICTRL] & MM67INT_HOUR) f = MM67INT_HOUR;
/* Roll over? */
if (regs[MM67_HOUR] >= RTC_BCD(24)) {
/* Update and set interrupt if needed. */
regs[MM67_HOUR] = RTC_BCD(0);
regs[MM67_DOW] = RTC_BCDINC(regs[MM67_DOW], 1);
if (regs[MM67_ICTRL] & MM67INT_DAY) f = MM67INT_DAY;
/* Roll over? */
if (regs[MM67_DOW] > RTC_BCD(7)) {
/* Update and set interrupt if needed. */
regs[MM67_DOW] = RTC_BCD(1);
if (regs[MM67_ICTRL] & MM67INT_WEEK) f = MM67INT_WEEK;
}
/* Roll over? */
regs[MM67_DOM] = RTC_BCDINC(regs[MM67_DOM], 1);
mon = RTC_DCB(regs[MM67_MON]);
if (dev->year != -1) {
year = RTC_DCB(regs[dev->year]);
if (dev->flags & FLAG_YEAR80)
year += 80;
} else
year = 80;
year += 1900;
if (RTC_DCB(regs[MM67_DOM]) > nvr_get_days(mon, year)) {
/* Update and set interrupt if needed. */
regs[MM67_DOM] = RTC_BCD(1);
regs[MM67_MON] = RTC_BCDINC(regs[MM67_MON], 1);
if (regs[MM67_ICTRL] & MM67INT_MON) f = MM67INT_MON;
/* Roll over? */
if (regs[MM67_MON] > RTC_BCD(12)) {
/* Update. */
regs[MM67_MON] = RTC_BCD(1);
if (dev->year != -1) {
year++;
if (dev->flags & FLAG_YEAR80)
year -= 80;
if (dev->flags & FLAG_YEARBCD)
regs[dev->year] = RTC_BCD(year % 100);
else
regs[dev->year] = year % 100;
}
}
}
}
}
}
/* Check for programmed alarm interrupt. */
if (regs[MM67_ICTRL] & MM67INT_COMPARE) {
year = 1;
for (mon = MM67_AL_SEC; mon <= MM67_AL_MON; mon++)
if (mon != dev->year)
year &= mm67_chkalrm(nvr, mon);
f = year ? MM67INT_COMPARE : 0x00;
}
/* Raise the IRQ if needed (and if we have one..) */
if (f != 0) {
regs[MM67_ISTAT] = f;
if (nvr->irq != -1)
picint(1 << nvr->irq);
}
}
/* Get the current NVR time. */
static void
mm67_time_get(nvr_t *nvr, struct tm *tm)
{
rtcdev_t *dev = (rtcdev_t *)nvr->data;
uint8_t *regs = nvr->regs;
/* NVR is in BCD data mode. */
tm->tm_sec = RTC_DCB(regs[MM67_SEC]);
tm->tm_min = RTC_DCB(regs[MM67_MIN]);
tm->tm_hour = RTC_DCB(regs[MM67_HOUR]);
tm->tm_wday = (RTC_DCB(regs[MM67_DOW]) - 1);
tm->tm_mday = RTC_DCB(regs[MM67_DOM]);
tm->tm_mon = (RTC_DCB(regs[MM67_MON]) - 1);
if (dev->year != -1) {
if (dev->flags & FLAG_YEARBCD)
tm->tm_year = RTC_DCB(regs[dev->year]);
else
tm->tm_year = regs[dev->year];
if (dev->flags & FLAG_YEAR80)
tm->tm_year += 80;
#ifdef MM67_CENTURY
tm->tm_year += (regs[MM67_CENTURY] * 100) - 1900;
#endif
#if ISARTC_DEBUG > 1
pclog("ISARTC: get_time: year=%i [%02x]\n", tm->tm_year, regs[dev->year]);
#endif
}
}
/* Set the current NVR time. */
static void
mm67_time_set(nvr_t *nvr, struct tm *tm)
{
rtcdev_t *dev = (rtcdev_t *)nvr->data;
uint8_t *regs = nvr->regs;
int year;
/* NVR is in BCD data mode. */
regs[MM67_SEC] = RTC_BCD(tm->tm_sec);
regs[MM67_MIN] = RTC_BCD(tm->tm_min);
regs[MM67_HOUR] = RTC_BCD(tm->tm_hour);
regs[MM67_DOW] = RTC_BCD(tm->tm_wday + 1);
regs[MM67_DOM] = RTC_BCD(tm->tm_mday);
regs[MM67_MON] = RTC_BCD(tm->tm_mon + 1);
if (dev->year != -1) {
year = tm->tm_year;
if (dev->flags & FLAG_YEAR80)
year -= 80;
if (dev->flags & FLAG_YEARBCD)
regs[dev->year] = RTC_BCD(year % 100);
else
regs[dev->year] = year % 100;
#ifdef MM67_CENTURY
regs[MM67_CENTURY] = (year + 1900) / 100;
#endif
#if ISARTC_DEBUG > 1
pclog("ISARTC: set_time: [%02x] year=%i (%i)\n", regs[dev->year], year, tm->tm_year);
#endif
}
}
static void
mm67_start(nvr_t *nvr)
{
struct tm tm;
/* Initialize the internal and chip times. */
if (time_sync) {
/* Use the internal clock's time. */
nvr_time_get(&tm);
mm67_time_set(nvr, &tm);
} else {
/* Set the internal clock from the chip time. */
mm67_time_get(nvr, &tm);
nvr_time_set(&tm);
}
}
/* Reset the RTC counters to a sane state. */
static void
mm67_reset(nvr_t *nvr)
{
int i;
/* Initialize the RTC to a known state. */
for (i = MM67_MSEC; i <= MM67_MON; i++)
nvr->regs[i] = RTC_BCD(0);
nvr->regs[MM67_DOW] = RTC_BCD(1);
nvr->regs[MM67_DOM] = RTC_BCD(1);
nvr->regs[MM67_MON] = RTC_BCD(1);
}
/* Handle a READ operation from one of our registers. */
static uint8_t
mm67_read(uint16_t port, void *priv)
{
rtcdev_t *dev = (rtcdev_t *)priv;
int reg = port - dev->base_addr;
uint8_t ret = 0xff;
/* This chip is directly mapped on I/O. */
cycles -= ISA_CYCLES(4);
switch(reg) {
case MM67_ISTAT: /* IRQ status (RO) */
ret = dev->nvr.regs[reg];
dev->nvr.regs[reg] = 0x00;
if (dev->irq != -1)
picintc(1 << dev->irq);
break;
default:
ret = dev->nvr.regs[reg];
break;
}
#if ISARTC_DEBUG
pclog("ISARTC: read(%04x) = %02x\n", port-dev->base_addr, ret);
#endif
return(ret);
}
/* Handle a WRITE operation to one of our registers. */
static void
mm67_write(uint16_t port, uint8_t val, void *priv)
{
rtcdev_t *dev = (rtcdev_t *)priv;
int reg = port - dev->base_addr;
int i;
#if ISARTC_DEBUG
pclog("ISARTC: write(%04x, %02x)\n", port-dev->base_addr, val);
#endif
/* This chip is directly mapped on I/O. */
cycles -= ISA_CYCLES(4);
switch(reg) {
case MM67_ISTAT: /* intr status (RO) */
break;
case MM67_ICTRL: /* intr control */
dev->nvr.regs[MM67_ISTAT] = 0x00;
dev->nvr.regs[reg] = val;
break;
case MM67_RSTCTR:
if (val == 0xff)
mm67_reset(&dev->nvr);
break;
case MM67_RSTRAM:
if (val == 0xff) {
for (i = MM67_AL_MSEC; i <= MM67_AL_MON; i++)
dev->nvr.regs[i] = RTC_BCD(0);
dev->nvr.regs[MM67_DOW] = RTC_BCD(1);
dev->nvr.regs[MM67_DOM] = RTC_BCD(1);
dev->nvr.regs[MM67_MON] = RTC_BCD(1);
if (dev->year != -1) {
val = (dev->flags & FLAG_YEAR80) ? 0 : 80;
if (dev->flags & FLAG_YEARBCD)
dev->nvr.regs[dev->year] = RTC_BCD(val);
else
dev->nvr.regs[dev->year] = val;
#ifdef MM67_CENTURY
dev->nvr.regs[MM67_CENTURY] = 19;
#endif
}
}
break;
case MM67_STATUS: /* STATUS (RO) */
break;
case MM67_GOCMD:
pclog("RTC: write gocmd=%02x\n", val);
break;
case MM67_STBYIRQ:
pclog("RTC: write stby=%02x\n", val);
break;
case MM67_TEST:
pclog("RTC: write test=%02x\n", val);
break;
default:
dev->nvr.regs[reg] = val;
break;
}
}
/************************************************************************
* *
* Generic code for all supported chips. *
* *
************************************************************************/
/* Initialize the device for use. */
static void *
isartc_init(const device_t *info)
{
rtcdev_t *dev;
/* Create a device instance. */
dev = (rtcdev_t *)malloc(sizeof(rtcdev_t));
memset(dev, 0x00, sizeof(rtcdev_t));
dev->name = info->name;
dev->board = info->local;
dev->irq = -1;
dev->year = -1;
dev->nvr.data = dev;
dev->nvr.size = 16;
/* Do per-board initialization. */
switch(dev->board) {
case 0: /* Everex EV-170 Magic I/O */
dev->flags |= FLAG_YEAR80;
dev->base_addr = device_get_config_hex16("base");
dev->base_addrsz = 32;
dev->irq = device_get_config_int("irq");
dev->f_rd = mm67_read;
dev->f_wr = mm67_write;
dev->nvr.reset = mm67_reset;
dev->nvr.start = mm67_start;
dev->nvr.tick = mm67_tick;
dev->year = MM67_AL_DOM; /* year, NON STANDARD */
break;
case 1: /* DTK PII-147 Hexa I/O Plus */
dev->flags |= FLAG_YEARBCD;
dev->base_addr = device_get_config_hex16("base");
dev->base_addrsz = 32;
dev->f_rd = mm67_read;
dev->f_wr = mm67_write;
dev->nvr.reset = mm67_reset;
dev->nvr.start = mm67_start;
dev->nvr.tick = mm67_tick;
dev->year = MM67_AL_HUNTEN; /* year, NON STANDARD */
break;
case 2: /* Paradise Systems 5PAK */
dev->flags |= FLAG_YEAR80;
dev->base_addr = 0x02c0;
dev->base_addrsz = 32;
dev->irq = device_get_config_int("irq");
dev->f_rd = mm67_read;
dev->f_wr = mm67_write;
dev->nvr.reset = mm67_reset;
dev->nvr.start = mm67_start;
dev->nvr.tick = mm67_tick;
dev->year = MM67_AL_DOM; /* year, NON STANDARD */
break;
default:
break;
}
/* Say hello! */
pclog("ISARTC: %s (I/O=%04XH", info->name, dev->base_addr);
if (dev->irq != -1)
pclog(", IRQ%i", dev->irq);
pclog(")\n");
/* Set up an I/O port handler. */
io_sethandler(dev->base_addr, dev->base_addrsz,
dev->f_rd,NULL,NULL, dev->f_wr,NULL,NULL, dev);
/* Hook into the NVR backend. */
dev->nvr.fn = (wchar_t *)isartc_get_internal_name(isartc_type);
dev->nvr.irq = dev->irq;
nvr_init(&dev->nvr);
/* Let them know our device instance. */
return((void *)dev);
}
/* Remove the device from the system. */
static void
isartc_close(void *priv)
{
rtcdev_t *dev = (rtcdev_t *)priv;
io_removehandler(dev->base_addr, dev->base_addrsz,
dev->f_rd,NULL,NULL, dev->f_wr,NULL,NULL, dev);
if (dev->nvr.fn != NULL)
free((wchar_t *)dev->nvr.fn);
free(dev);
}
static const device_config_t ev170_config[] = {
{
"base", "Address", CONFIG_HEX16, "", 0x02C0,
{
{
"240H", 0x0240
},
{
"2C0H", 0x02c0
},
{
""
}
},
},
{
"irq", "IRQ", CONFIG_SELECTION, "", -1,
{
{
"Disabled", -1
},
{
"IRQ2", 2
},
{
"IRQ5", 5
},
{
"IRQ7", 7
},
{
""
}
},
},
{
"", "", -1
}
};
static const device_t ev170_device = {
"Everex EV-170 Magic I/O",
DEVICE_ISA,
0,
isartc_init, isartc_close, NULL,
NULL, NULL, NULL,
ev170_config
};
static const device_config_t pii147_config[] = {
{
"base", "Address", CONFIG_HEX16, "", 0x0240,
{
{
"Clock 1", 0x0240
},
{
"Clock 2", 0x0340
},
{
""
}
},
},
{
"", "", -1
}
};
static const device_t pii147_device = {
"DTK PII-147 Hexa I/O Plus",
DEVICE_ISA,
1,
isartc_init, isartc_close, NULL,
NULL, NULL, NULL,
pii147_config
};
static const device_config_t p5pak_config[] = {
{
"irq", "IRQ", CONFIG_SELECTION, "", -1,
{
{
"Disabled", -1
},
{
"IRQ2", 2
},
{
"IRQ3", 3
},
{
"IRQ5", 5
},
{
""
}
},
},
{
"", "", -1
}
};
static const device_t p5pak_device = {
"Paradise Systems 5-PAK",
DEVICE_ISA,
2,
isartc_init, isartc_close, NULL,
NULL, NULL, NULL,
p5pak_config
};
static const struct {
const char *name;
const char *internal_name;
const device_t *dev;
} boards[] = {
{ "None", "none", NULL, },
{ "Everex EV-170 Magic I/O", "ev170", &ev170_device, },
{ "DTK PII-147 Hexa I/O Plus", "pii147", &pii147_device, },
{ "Paradise Systems 5-PAK", "p5pak", &p5pak_device, },
{ "", "", NULL, },
};
void
isartc_reset(void)
{
if (isartc_type == 0) return;
/* Add the device to the system. */
device_add(boards[isartc_type].dev);
}
char *
isartc_get_name(int board)
{
return((char *)boards[board].name);
}
char *
isartc_get_internal_name(int board)
{
return((char *)boards[board].internal_name);
}
int
isartc_get_from_internal_name(char *s)
{
int c = 0;
while (strlen((char *) boards[c].internal_name)) {
if (! strcmp(boards[c].internal_name, s))
return(c);
c++;
}
/* Not found. */
return(0);
}
const device_t *
isartc_get_device(int board)
{
return(boards[board].dev);
}

71
src/isartc.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* 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 ISARTC cards.
*
* Version: @(#)isartc.h 1.0.1 2018/08/27
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
*
* 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 ISARTC_H
# define ISARTC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Global variables. */
/* Functions. */
extern void isartc_reset(void);
extern char *isartc_get_name(int t);
extern char *isartc_get_internal_name(int t);
extern int isartc_get_from_internal_name(char *s);
extern const device_t *isartc_get_device(int t);
#ifdef __cplusplus
}
#endif
#endif /*ISARTC_H*/

View File

@@ -1,3 +1,41 @@
/*
* 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.
*
* Standard PC/AT implementation.
*
* Version: @(#)m_at.c 1.0.0 2018/09/02
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -46,6 +84,16 @@ machine_at_init(const machine_t *model)
} }
void
machine_at_ibm_init(const machine_t *model)
{
machine_at_init(model);
mem_remap_top(384);
device_add(&fdc_at_device);
}
void void
machine_at_ps2_init(const machine_t *model) machine_at_ps2_init(const machine_t *model)
{ {
@@ -80,30 +128,3 @@ machine_at_ps2_ide_init(const machine_t *model)
device_add(&ide_isa_2ch_opt_device); device_add(&ide_isa_2ch_opt_device);
} }
void
machine_at_top_remap_init(const machine_t *model)
{
machine_at_init(model);
mem_remap_top_384k();
}
void
machine_at_ide_top_remap_init(const machine_t *model)
{
machine_at_ide_init(model);
mem_remap_top_384k();
}
void
machine_at_ibm_init(const machine_t *model)
{
machine_at_top_remap_init(model);
device_add(&fdc_at_device);
}

View File

@@ -1,3 +1,41 @@
/*
* 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 the Commodore PC3 system.
*
* Version: @(#)m_at_commodore.c 1.0.0 2018/09/02
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -5,6 +43,7 @@
#include "../86box.h" #include "../86box.h"
#include "../device.h" #include "../device.h"
#include "../io.h" #include "../io.h"
#include "../mem.h"
#include "../lpt.h" #include "../lpt.h"
#include "../serial.h" #include "../serial.h"
#include "../floppy/fdd.h" #include "../floppy/fdd.h"
@@ -48,7 +87,10 @@ static void cbm_io_init()
void void
machine_at_cmdpc_init(const machine_t *model) machine_at_cmdpc_init(const machine_t *model)
{ {
machine_at_ide_top_remap_init(model); machine_at_ide_init(model);
mem_remap_top(384);
device_add(&fdc_at_device); device_add(&fdc_at_device);
cbm_io_init(); cbm_io_init();

View File

@@ -8,7 +8,7 @@
* *
* Emulation of various Compaq PC's. * Emulation of various Compaq PC's.
* *
* Version: @(#)m_at_compaq.c 1.0.5 2018/03/18 * Version: @(#)m_at_compaq.c 1.0.6 2018/09/02
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -100,7 +100,10 @@ write_raml(uint32_t addr, uint32_t val, void *priv)
void void
machine_at_compaq_init(const machine_t *model) machine_at_compaq_init(const machine_t *model)
{ {
machine_at_top_remap_init(model); machine_at_init(model);
mem_remap_top(384);
device_add(&fdc_at_device); device_add(&fdc_at_device);
mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000,

View File

@@ -523,9 +523,6 @@ headland_init(void)
mem_mapping_disable(&headland_ems_mapping[i]); mem_mapping_disable(&headland_ems_mapping[i]);
} }
for(i=4; i<10; i++)
isram[i] = 0;
headland_memmap_state_update(); headland_memmap_state_update();
} }

View File

@@ -1,89 +1,851 @@
/* Copyright holders: Sarah Walker /*
see COPYING for more details * 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.
*
* Emulation of C&T CS8121 ("NEAT") 82C206/211/212/215 chipset.
*
* Note: The datasheet mentions that the chipset supports up to 8MB
* of DRAM. This is intepreted as 'being able to refresh up to
* 8MB of DRAM chips', because it works fine with bus-based
* memory expansion.
*
* Version: @(#)m_at_neat.c 1.0.1 2018/07/22
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*
* 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.
*/ */
/*This is the chipset used in the AMI 286 clone model*/
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#include "../86box.h" #include "../86box.h"
#include "../device.h" #include "../device.h"
#include "../io.h" #include "../cpu/cpu.h"
#include "../keyboard.h" #include "../cpu/x86.h"
#include "../floppy/fdd.h" #include "../floppy/fdd.h"
#include "../floppy/fdc.h" #include "../floppy/fdc.h"
#include "../keyboard.h"
#include "../io.h"
#include "../mem.h"
#include "../nmi.h"
#include "../rom.h"
#include "machine.h" #include "machine.h"
#define NEAT_DEBUG 0
static uint8_t neat_regs[256];
static int neat_index;
static int neat_emspage[4];
static void neat_write(uint16_t port, uint8_t val, void *priv) #define EMS_MAXPAGE 4
#define EMS_PGSIZE 16384
/* CS8221 82C211 controller registers. */
#define REG_RA0 0x60 /* PROCCLK selector */
# define RA0_MASK 0x34 /* RR11 X1XR */
# define RA0_READY 0x01 /* local bus READY timeout */
# define RA0_RDYNMIEN 0x04 /* local bus READY tmo NMI enable */
# define RA0_PROCCLK 0x10 /* PROCCLK=BCLK (1) or CLK2IN (0) */
# define RA0_ALTRST 0x20 /* alternate CPU reset (1) */
# define RA0_REV 0xc0 /* chip revision ID */
# define RA0_REV_SH 6
# define RA0_REV_ID 2 /* faked revision# for 82C211 */
#define REG_RA1 0x61 /* Command Delay */
# define RA1_MASK 0xff /* 1111 1111 */
# define RA1_BUSDLY 0x03 /* AT BUS command delay */
# define RA1_BUSDLY_SH 0
# define RA1_BUS8DLY 0x0c /* AT BUS 8bit command delay */
# define RA1_BUS8DLY_SH 2
# define RA1_MEMDLY 0x30 /* AT BUS 16bit memory delay */
# define RA1_MEMDLY_SH 4
# define RA1_QUICKEN 0x40 /* Quick Mode enable */
# define RA1_HOLDDLY 0x80 /* Hold Time Delay */
#define REG_RA2 0x62 /* Wait State / BCLK selector */
# define RA2_MASK 0x3f /* XX11 1111 */
# define RA2_BCLK 0x03 /* BCLK select */
# define RA2_BCLK_SH 0
# define BCLK_IN2 0 /* BCLK = CLK2IN/2 */
# define BCLK_IN 1 /* BCLK = CLK2IN */
# define BCLK_AT 2 /* BCLK = ATCLK */
# define RA2_AT8WS 0x0c /* AT 8-bit wait states */
# define RA2_AT8WS_SH 2
# define AT8WS_2 0 /* 2 wait states */
# define AT8WS_3 1 /* 3 wait states */
# define AT8WS_4 2 /* 4 wait states */
# define AT8WS_5 4 /* 5 wait states */
# define RA2_ATWS 0x30 /* AT 16-bit wait states */
# define RA2_ATWS_SH 4
# define ATWS_2 0 /* 2 wait states */
# define ATWS_3 1 /* 3 wait states */
# define ATWS_4 2 /* 4 wait states */
# define ATWS_5 4 /* 5 wait states */
/* CS8221 82C212 controller registers. */
#define REG_RB0 0x64 /* Version ID */
# define RB0_MASK 0x60 /* R11X XXXX */
# define RB0_REV 0x60 /* Chip revsion number */
# define RB0_REV_SH 5
# define RB0_REV_ID 2 /* faked revision# for 82C212 */
# define RB0_VERSION 0x80 /* Chip version (0=82C212) */
#define REG_RB1 0x65 /* ROM configuration */
# define RB1_MASK 0xff /* 1111 1111 */
# define RB1_ROMF0 0x01 /* ROM F0000 enabled (0) */
# define RB1_ROME0 0x02 /* ROM E0000 disabled (1) */
# define RB1_ROMD0 0x04 /* ROM D0000 disabled (1) */
# define RB1_ROMC0 0x08 /* ROM C0000 disabled (1) */
# define RB1_SHADOWF0 0x10 /* Shadow F0000 R/W (0) */
# define RB1_SHADOWE0 0x20 /* Shadow E0000 R/W (0) */
# define RB1_SHADOWD0 0x40 /* Shadow D0000 R/W (0) */
# define RB1_SHADOWC0 0x80 /* Shadow C0000 R/W (0) */
#define REG_RB2 0x66 /* Memory Enable 1 */
# define RB2_MASK 0x80 /* 1XXX XXXX */
# define RB2_TOP128 0x80 /* top 128K is on sysboard (1) */
#define REG_RB3 0x67 /* Memory Enable 2 */
# define RB3_MASK 0xff /* 1111 1111 */
# define RB3_SHENB0 0x01 /* enable B0000-B3FFF shadow (1) */
# define RB3_SHENB4 0x02 /* enable B4000-B7FFF shadow (1) */
# define RB3_SHENB8 0x04 /* enable B8000-BBFFF shadow (1) */
# define RB3_SHENBC 0x08 /* enable BC000-BFFFF shadow (1) */
# define RB3_SHENA0 0x10 /* enable A0000-A3FFF shadow (1) */
# define RB3_SHENA4 0x20 /* enable A4000-A7FFF shadow (1) */
# define RB3_SHENA8 0x40 /* enable A8000-ABFFF shadow (1) */
# define RB3_SHENAC 0x80 /* enable AC000-AFFFF shadow (1) */
#define REG_RB4 0x68 /* Memory Enable 3 */
# define RB4_MASK 0xff /* 1111 1111 */
# define RB4_SHENC0 0x01 /* enable C0000-C3FFF shadow (1) */
# define RB4_SHENC4 0x02 /* enable C4000-C7FFF shadow (1) */
# define RB4_SHENC8 0x04 /* enable C8000-CBFFF shadow (1) */
# define RB4_SHENCC 0x08 /* enable CC000-CFFFF shadow (1) */
# define RB4_SHEND0 0x10 /* enable D0000-D3FFF shadow (1) */
# define RB4_SHEND4 0x20 /* enable D4000-D7FFF shadow (1) */
# define RB4_SHEND8 0x40 /* enable D8000-DBFFF shadow (1) */
# define RB4_SHENDC 0x80 /* enable DC000-DFFFF shadow (1) */
#define REG_RB5 0x69 /* Memory Enable 4 */
# define RB5_MASK 0xff /* 1111 1111 */
# define RB5_SHENE0 0x01 /* enable E0000-E3FFF shadow (1) */
# define RB5_SHENE4 0x02 /* enable E4000-E7FFF shadow (1) */
# define RB5_SHENE8 0x04 /* enable E8000-EBFFF shadow (1) */
# define RB5_SHENEC 0x08 /* enable EC000-EFFFF shadow (1) */
# define RB5_SHENF0 0x10 /* enable F0000-F3FFF shadow (1) */
# define RB5_SHENF4 0x20 /* enable F4000-F7FFF shadow (1) */
# define RB5_SHENF8 0x40 /* enable F8000-FBFFF shadow (1) */
# define RB5_SHENFC 0x80 /* enable FC000-FFFFF shadow (1) */
#define REG_RB6 0x6a /* Bank 0/1 Enable */
# define RB6_MASK 0xe0 /* 111R RRRR */
# define RB6_BANKS 0x20 /* #banks used (1=two) */
# define RB6_RTYPE 0xc0 /* DRAM chip size used */
# define RTYPE_SH 6
# define RTYPE_NONE 0 /* Disabled */
# define RTYPE_MIXED 1 /* 64K/256K mixed (for 640K) */
# define RTYPE_256K 2 /* 256K (default) */
# define RTYPE_1M 3 /* 1M */
#define REG_RB7 0x6b /* DRAM configuration */
# define RB7_MASK 0xff /* 1111 1111 */
# define RB7_ROMWS 0x03 /* ROM access wait states */
# define RB7_ROMWS_SH 0
# define ROMWS_0 0 /* 0 wait states */
# define ROMWS_1 1 /* 1 wait states */
# define ROMWS_2 2 /* 2 wait states */
# define ROMWS_3 3 /* 3 wait states (default) */
# define RB7_EMSWS 0x0c /* EMS access wait states */
# define RB7_EMSWS_SH 2
# define EMSWS_0 0 /* 0 wait states */
# define EMSWS_1 1 /* 1 wait states */
# define EMSWS_2 2 /* 2 wait states */
# define EMSWS_3 3 /* 3 wait states (default) */
# define RB7_EMSEN 0x10 /* enable EMS (1=on) */
# define RB7_RAMWS 0x20 /* RAM access wait state (1=1ws) */
# define RB7_UMAREL 0x40 /* relocate 640-1024K to 1M */
# define RB7_PAGEEN 0x80 /* enable Page/Interleaved mode */
#define REG_RB8 0x6c /* Bank 2/3 Enable */
# define RB8_MASK 0xf0 /* 1111 RRRR */
# define RB8_4WAY 0x10 /* enable 4-way interleave mode */
# define RB8_BANKS 0x20 /* enable 2 banks (1) */
# define RB8_RTYPE 0xc0 /* DRAM chip size used */
# define RB8_RTYPE_SH 6
#define REG_RB9 0x6d /* EMS base address */
# define RB9_MASK 0xff /* 1111 1111 */
# define RB9_BASE 0x0f /* I/O base address selection */
# define RB9_BASE_SH 0
# define RB9_FRAME 0xf0 /* frame address selection */
# define RB9_FRAME_SH 4
#define REG_RB10 0x6e /* EMS address extension */
# define RB10_MASK 0xff /* 1111 1111 */
# define RB10_P3EXT 0x03 /* page 3 extension */
# define RB10_P3EXT_SH 0
# define PEXT_0M 0 /* page is at 0-2M */
# define PEXT_2M 1 /* page is at 2-4M */
# define PEXT_4M 2 /* page is at 4-6M */
# define PEXT_6M 3 /* page is at 6-8M */
# define RB10_P2EXT 0x0c /* page 2 extension */
# define RB10_P2EXT_SH 2
# define RB10_P1EXT 0x30 /* page 1 extension */
# define RB10_P1EXT_SH 4
# define RB10_P0EXT 0xc0 /* page 0 extension */
# define RB10_P0EXT_SH 6
#define REG_RB11 0x6f /* Miscellaneous */
# define RB11_MASK 0xe6 /* 111R R11R */
# define RB11_GA20 0x02 /* gate for A20 */
# define RB11_RASTMO 0x04 /* enable RAS timeout counter */
# define RB11_EMSLEN 0xe0 /* EMS memory chunk size */
# define RB11_EMSLEN_SH 5
typedef struct {
int8_t enabled; /* 1=ENABLED */
char pad;
uint16_t page; /* selected page in EMS block */
uint32_t start; /* start of EMS in RAM */
uint8_t *addr; /* start addr in EMS RAM */
mem_mapping_t mapping; /* mapping entry for page */
} emspage_t;
typedef struct {
uint8_t regs[128]; /* all the CS8221 registers */
uint8_t indx; /* programmed index into registers */
char pad;
uint16_t ems_base, /* configured base address */
ems_oldbase;
uint32_t ems_frame, /* configured frame address */
ems_oldframe;
uint16_t ems_size, /* EMS size in KB */
ems_pages; /* EMS size in pages */
emspage_t ems[EMS_MAXPAGE]; /* EMS page registers */
} neat_t;
/* Read one byte from paged RAM. */
static uint8_t
ems_readb(uint32_t addr, void *priv)
{ {
switch (port) mem_mapping_t *map = (mem_mapping_t *)priv;
{ neat_t *dev = (neat_t *)map->dev;
case 0x22: uint8_t ret = 0xff;
neat_index = val; int vpage;
break;
case 0x23:
neat_regs[neat_index] = val;
switch (neat_index)
{
case 0x6E: /*EMS page extension*/
neat_emspage[3] = (neat_emspage[3] & 0x7F) | (( val & 3) << 7);
neat_emspage[2] = (neat_emspage[2] & 0x7F) | (((val >> 2) & 3) << 7);
neat_emspage[1] = (neat_emspage[1] & 0x7F) | (((val >> 4) & 3) << 7);
neat_emspage[0] = (neat_emspage[0] & 0x7F) | (((val >> 6) & 3) << 7);
break;
}
break;
case 0x0208: case 0x0209: case 0x4208: case 0x4209: /* Get the viewport page number. */
case 0x8208: case 0x8209: case 0xC208: case 0xC209: vpage = ((addr & 0xffff) / EMS_PGSIZE);
neat_emspage[port >> 14] = (neat_emspage[port >> 14] & 0x180) | (val & 0x7F);
break; /* Grab the data. */
} ret = *(uint8_t *)(dev->ems[vpage].addr + (addr - map->base));
return(ret);
} }
/* Read one word from paged RAM. */
static uint8_t neat_read(uint16_t port, void *priv) static uint16_t
ems_readw(uint32_t addr, void *priv)
{ {
switch (port) mem_mapping_t *map = (mem_mapping_t *)priv;
{ neat_t *dev = (neat_t *)map->dev;
case 0x22: uint16_t ret = 0xffff;
return neat_index; int vpage;
case 0x23: /* Get the viewport page number. */
return neat_regs[neat_index]; vpage = ((addr & 0xffff) / EMS_PGSIZE);
}
return 0xff; /* Grab the data. */
ret = *(uint16_t *)(dev->ems[vpage].addr + (addr - map->base));
return(ret);
} }
/* Write one byte to paged RAM. */
#if NOT_USED static void
static void neat_writeems(uint32_t addr, uint8_t val) ems_writeb(uint32_t addr, uint8_t val, void *priv)
{ {
ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)] = val; 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);
/* Write the data. */
*(uint8_t *)(dev->ems[vpage].addr + (addr - map->base)) = val;
} }
/* Write one word to paged RAM. */
static uint8_t neat_readems(uint32_t addr) static void
ems_writew(uint32_t addr, uint16_t val, void *priv)
{ {
return ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)]; 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);
/* Write the data. */
*(uint16_t *)(dev->ems[vpage].addr + (addr - map->base)) = val;
} }
/* Re-calculate the active-page physical address. */
static void
ems_recalc(neat_t *dev, emspage_t *ems)
{
if (ems->page >= dev->ems_pages) {
/* That page does not exist. */
ems->enabled = 0;
}
/* Pre-calculate the page address in EMS RAM. */
ems->addr = ram + ems->start + (ems->page * EMS_PGSIZE);
if (ems->enabled) {
/* Update the EMS RAM address for this page. */
mem_mapping_set_exec(&ems->mapping, ems->addr);
/* Enable this page. */
mem_mapping_enable(&ems->mapping);
#if NEAT_DEBUG > 1
pclog("NEAT EMS: page %d set to %08lx, %sabled)\n",
ems->page, ems->addr-ram, ems->enabled?"en":"dis");
#endif
} else {
/* Disable this page. */
mem_mapping_disable(&ems->mapping);
}
}
static void
ems_write(uint16_t port, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *)priv;
emspage_t *ems;
int vpage;
#if NEAT_DEBUG > 1
pclog("NEAT: ems_write(%04x, %02x)\n", port, val);
#endif #endif
/* Get the viewport page number. */
vpage = (port / EMS_PGSIZE);
ems = &dev->ems[vpage];
static void neat_init(void) switch(port & 0x000f) {
case 0x0008:
case 0x0009:
ems->enabled = !!(val & 0x80);
ems->page &= 0x0180; /* clear lower bits */
ems->page |= (val & 0x7f); /* add new bits */
ems_recalc(dev, ems);
break;
}
}
static uint8_t
ems_read(uint16_t port, void *priv)
{ {
io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); neat_t *dev = (neat_t *)priv;
io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); uint8_t ret = 0xff;
io_sethandler(0x4208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); int vpage;
io_sethandler(0x8208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL);
io_sethandler(0xc208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); /* Get the viewport page number. */
vpage = (port / EMS_PGSIZE);
switch(port & 0x000f) {
case 0x0008: /* page number register */
ret = dev->ems[vpage].page & 0x7f;
if (dev->ems[vpage].enabled)
ret |= 0x80;
break;
}
#if NEAT_DEBUG > 1
pclog("NEAT: ems_read(%04x) = %02x\n", port, ret);
#endif
return(ret);
}
/* Initialize the EMS module. */
static void
ems_init(neat_t *dev, int en)
{
int i;
/* Remove if needed. */
if (! en) {
if (dev->ems_base > 0) for (i = 0; i < EMS_MAXPAGE; i++) {
/* Disable for now. */
mem_mapping_disable(&dev->ems[i].mapping);
/* Remove I/O handler. */
io_removehandler(dev->ems_base + (i * EMS_PGSIZE), 2,
ems_read,NULL,NULL, ems_write,NULL,NULL, dev);
}
pclog("NEAT: EMS disabled\n");
return;
}
/* Get configured I/O address. */
i = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH;
dev->ems_base = 0x0208 + (0x10 * i);
/* Get configured frame address. */
i = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH;
dev->ems_frame = 0xC0000 + (EMS_PGSIZE * i);
/*
* 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->ems_frame + (EMS_PGSIZE*i), EMS_PGSIZE,
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);
/* Disable for now. */
mem_mapping_disable(&dev->ems[i].mapping);
/* Set up an I/O port handler. */
io_sethandler(dev->ems_base + (i * EMS_PGSIZE), 2,
ems_read,NULL,NULL, ems_write,NULL,NULL, dev);
/*
* TODO: update the 'high_mem' mapping to reflect that we now
* have NN MB less extended memory available..
*/
}
pclog("NEAT: EMS enabled, I/O=%04xH, Frame=%05XH\n",
dev->ems_base, dev->ems_frame);
}
static void
neat_write(uint16_t port, uint8_t val, void *priv)
{
neat_t *dev = (neat_t *)priv;
uint8_t xval, *reg;
int i;
#if NEAT_DEBUG > 2
pclog("NEAT: write(%04x, %02x)\n", port, val);
#endif
switch (port) {
case 0x22:
dev->indx = val;
break;
case 0x23:
reg = &dev->regs[dev->indx];
xval = *reg ^ val;
switch (dev->indx) {
case REG_RA0:
val &= RA0_MASK;
*reg = (*reg & ~RA0_MASK) | val | \
(RA0_REV_ID << RA0_REV_SH);
#if NEAT_DEBUG > 1
pclog("NEAT: RA0=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RA1:
val &= RA1_MASK;
*reg = (*reg & ~RA1_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RA1=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RA2:
val &= RA2_MASK;
*reg = (*reg & ~RA2_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RA2=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB0:
val &= RB0_MASK;
*reg = (*reg & ~RB0_MASK) | val | \
(RB0_REV_ID << RB0_REV_SH);
#if NEAT_DEBUG > 1
pclog("NEAT: RB0=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB1:
val &= RB1_MASK;
*reg = (*reg & ~RB1_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB1=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB2:
val &= RB2_MASK;
*reg = (*reg & ~RB2_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB2=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB3:
val &= RB3_MASK;
*reg = (*reg & ~RB3_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB3=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB4:
val &= RB4_MASK;
*reg = (*reg & ~RB4_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB4=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB5:
val &= RB5_MASK;
*reg = (*reg & ~RB5_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB5=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB6:
val &= RB6_MASK;
*reg = (*reg & ~RB6_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB6=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB7:
val &= RB7_MASK;
*reg = (*reg & ~RB7_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB7=%02x(%02x)\n", val, *reg);
#endif
if (val & RB7_EMSEN)
ems_init(dev, 1);
else if (xval & RB7_EMSEN)
ems_init(dev, 0);
if (xval & RB7_UMAREL) {
if (val & RB7_UMAREL)
mem_remap_top(384);
else
mem_remap_top(0);
}
break;
case REG_RB8:
val &= RB8_MASK;
*reg = (*reg & ~RB8_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB8=%02x(%02x)\n", val, *reg);
#endif
break;
case REG_RB9:
val &= RB9_MASK;
*reg = (*reg & ~RB9_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB9=%02x(%02x)\n", val, *reg);
#endif
if (dev->regs[REG_RB7] & RB7_EMSEN) {
ems_init(dev, 0);
ems_init(dev, 1);
}
break;
case REG_RB10:
val &= RB10_MASK;
*reg = (*reg & ~RB10_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB10=%02x(%02x)\n", val, *reg);
#endif
dev->ems[3].start = ((val & RB10_P3EXT) >> RB10_P3EXT_SH) << 21;
dev->ems[2].start = ((val & RB10_P2EXT) >> RB10_P2EXT_SH) << 21;
dev->ems[1].start = ((val & RB10_P1EXT) >> RB10_P1EXT_SH) << 21;
dev->ems[0].start = ((val & RB10_P0EXT) >> RB10_P0EXT_SH) << 21;
for (i = 0; i < EMS_MAXPAGE; i++)
ems_recalc(dev, &dev->ems[i]);
break;
case REG_RB11:
val &= RB11_MASK;
*reg = (*reg & ~RB11_MASK) | val;
#if NEAT_DEBUG > 1
pclog("NEAT: RB11=%02x(%02x)\n", val, *reg);
#endif
i = (val & RB11_EMSLEN) >> RB11_EMSLEN_SH;
switch(i) {
case 0: /* "less than 2MB" */
dev->ems_size = 512;
break;
case 1: /* 1 MB */
case 2: /* 2 MB */
case 3: /* 3 MB */
case 4: /* 4 MB */
case 5: /* 5 MB */
case 6: /* 6 MB */
case 7: /* 7 MB */
dev->ems_size = i << 10;
break;
}
dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE;
if (dev->regs[REG_RB7] & RB7_EMSEN)
pclog("NEAT: EMS %iKB (%i pages)\n",
dev->ems_size, dev->ems_pages);
break;
default:
pclog("NEAT: inv write to reg %02x (%02x)\n",
dev->indx, val);
break;
}
break;
}
}
static uint8_t
neat_read(uint16_t port, void *priv)
{
neat_t *dev = (neat_t *)priv;
uint8_t ret = 0xff;
switch (port) {
case 0x22:
ret = dev->indx;
break;
case 0x23:
ret = dev->regs[dev->indx];
break;
default:
break;
}
#if NEAT_DEBUG > 2
pclog("NEAT: read(%04x) = %02x\n", port, ret);
#endif
return(ret);
}
static void
neat_init(void)
{
neat_t *dev;
int i;
/* Create an instance. */
dev = (neat_t *)malloc(sizeof(neat_t));
memset(dev, 0x00, sizeof(neat_t));
/* Initialize some of the registers to specific defaults. */
for (i = REG_RA0; i <= REG_RB11; i++) {
dev->indx = i;
neat_write(0x0023, 0x00, dev);
}
/*
* Based on the value of mem_size, we have to set up
* a proper DRAM configuration (so that EMS works.)
*
* TODO: We might also want to set 'valid' waitstate
* bits, based on our cpu speed.
*/
i = 0;
switch(mem_size) {
case 512: /* 512KB */
/* 256K, 0, 0, 0 */
dev->regs[REG_RB6] &= ~RB6_BANKS; /* one bank */
dev->regs[REG_RB6] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE<<RTYPE_SH); /* NONE */
i = 2;
break;
case 640: /* 640KB */
/* 256K, 64K, 0, 0 */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_MIXED<<RTYPE_SH); /* mixed */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE<<RTYPE_SH); /* NONE */
i = 4;
break;
case 1024: /* 1MB */
/* 256K, 256K, 0, 0 */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE<<RTYPE_SH); /* NONE */
i = 5;
break;
case 1536: /* 1.5MB */
/* 256K, 256K, 256K, 0 */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
i = 7;
break;
case 1664: /* 1.64MB */
/* 256K, 64K, 256K, 256K */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_MIXED<<RTYPE_SH); /* mixed */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
i = 10;
break;
case 2048: /* 2MB */
#if 1
/* 256K, 256K, 256K, 256K */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] |= RB8_4WAY; /* 4way intl */
i = 11;
#else
/* 1M, 0, 0, 0 */
dev->regs[REG_RB6] &= ~RB6_BANKS; /* one bank */
dev->regs[REG_RB6] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE<<RTYPE_SH); /* NONE */
i = 3;
#endif
break;
case 3072: /* 3MB */
/* 256K, 256K, 1M, 0 */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
i = 8;
break;
case 4096: /* 4MB */
/* 1M, 1M, 0, 0 */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_NONE<<RTYPE_SH); /* NONE */
i = 6;
break;
case 4224: /* 4.64MB */
/* 256K, 64K, 1M, 1M */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_MIXED<<RTYPE_SH); /* mixed */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
i = 12;
break;
case 5120: /* 5MB */
/* 256K, 256K, 1M, 1M */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_256K<<RTYPE_SH); /* 256K */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
i = 13;
break;
case 6144: /* 6MB */
/* 1M, 1M, 1M, 0 */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
dev->regs[REG_RB8] &= ~RB8_BANKS; /* one bank */
dev->regs[REG_RB8] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
i = 9;
break;
case 8192: /* 8MB */
/* 1M, 1M, 1M, 1M */
dev->regs[REG_RB6] |= RB6_BANKS; /* two banks */
dev->regs[REG_RB6] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
dev->regs[REG_RB8] |= RB8_BANKS; /* two banks */
dev->regs[REG_RB8] |= (RTYPE_1M<<RTYPE_SH); /* 1M */
dev->regs[REG_RB8] |= RB8_4WAY; /* 4way intl */
i = 14;
break;
default:
pclog("NEAT: **INVALID DRAM SIZE %iKB !**\n", mem_size);
}
if (i > 0)
pclog("NEAT: using DRAM mode #%i (mem=%iKB)\n", i, mem_size);
/* Set up an I/O handler for the chipset. */
io_sethandler(0x0022, 2,
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
} }
@@ -91,9 +853,10 @@ void
machine_at_neat_init(const machine_t *model) machine_at_neat_init(const machine_t *model)
{ {
machine_at_init(model); machine_at_init(model);
device_add(&fdc_at_device);
neat_init();
neat_init();
device_add(&fdc_at_device);
} }
@@ -102,8 +865,9 @@ machine_at_neat_ami_init(const machine_t *model)
{ {
machine_at_common_init(model); machine_at_common_init(model);
device_add(&keyboard_at_ami_device); neat_init();
device_add(&fdc_at_device);
device_add(&keyboard_at_ami_device);
neat_init();
device_add(&fdc_at_device);
} }

View File

@@ -10,7 +10,7 @@
* *
* Re-worked version based on the 82C235 datasheet and errata. * Re-worked version based on the 82C235 datasheet and errata.
* *
* Version: @(#)m_at_scat.c 1.0.15 2018/04/29 * Version: @(#)m_at_scat.c 1.0.16 2018/09/02
* *
* Authors: Original by GreatPsycho for PCem. * Authors: Original by GreatPsycho for PCem.
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
@@ -1259,7 +1259,6 @@ scat_init()
scat_port_92 = 0; scat_port_92 = 0;
mem_mapping_disable(&ram_low_mapping); mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_mid_mapping);
mem_mapping_disable(&ram_high_mapping); mem_mapping_disable(&ram_high_mapping);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
mem_mapping_disable(&bios_mapping[i]); mem_mapping_disable(&bios_mapping[i]);
@@ -1282,8 +1281,6 @@ scat_init()
mem_mapping_add(&scat_ems_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); mem_mapping_add(&scat_ems_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]);
} }
for(i=4;i<10;i++) isram[i] = 0;
for (i = (scat_regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) { for (i = (scat_regs[SCAT_VERSION] < 4 ? 0 : 8); i < 16; i++) {
mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), 0, NULL); mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), 0, NULL);
mem_mapping_enable(&scat_high_mapping[i]); mem_mapping_enable(&scat_high_mapping[i]);
@@ -1333,7 +1330,6 @@ scatsx_init()
scat_port_92 = 0; scat_port_92 = 0;
mem_mapping_disable(&ram_low_mapping); mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_mid_mapping);
mem_mapping_disable(&ram_high_mapping); mem_mapping_disable(&ram_high_mapping);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
mem_mapping_disable(&bios_mapping[i]); mem_mapping_disable(&bios_mapping[i]);

View File

@@ -28,7 +28,7 @@
* boot. Sometimes, they do, and then it shows an "Incorrect * boot. Sometimes, they do, and then it shows an "Incorrect
* DOS" error message?? --FvK * DOS" error message?? --FvK
* *
* Version: @(#)m_ps1.c 1.0.9 2018/04/26 * Version: @(#)m_ps1.c 1.0.10 2018/09/02
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -512,7 +512,7 @@ ps1_common_init(const machine_t *model)
{ {
machine_common_init(model); machine_common_init(model);
mem_remap_top_384k(); mem_remap_top(384);
pit_set_out_func(&pit, 1, pit_refresh_timer_at); pit_set_out_func(&pit, 1, pit_refresh_timer_at);

View File

@@ -1,3 +1,41 @@
/*
* 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 MCA-based PS/2 machines.
*
* Version: @(#)m_ps2_mca.c 1.0.0 2018/09/02
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -830,7 +868,7 @@ static void ps2_mca_board_model_50_init()
{ {
ps2_mca_board_common_init(); ps2_mca_board_common_init();
mem_remap_top_384k(); mem_remap_top(384);
mca_init(4); mca_init(4);
ps2.planar_read = model_50_read; ps2.planar_read = model_50_read;
@@ -864,7 +902,7 @@ static void ps2_mca_board_model_55sx_init()
NULL); NULL);
mem_remap_top_256k(); mem_remap_top(256);
ps2.option[3] = 0x10; ps2.option[3] = 0x10;
memset(ps2.memory_bank, 0xf0, 8); memset(ps2.memory_bank, 0xf0, 8);
@@ -1019,10 +1057,13 @@ static void mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p)
ps2.pending_cache_miss = 1; ps2.pending_cache_miss = 1;
if ((val & 0x21) == 0x01 && (old & 0x21) != 0x01) if ((val & 0x21) == 0x01 && (old & 0x21) != 0x01)
ps2_cache_clean(); ps2_cache_clean();
#if 1
// FIXME: Look into this!!!
if (val & 0x01) if (val & 0x01)
ram_mid_mapping.flags |= MEM_MAPPING_ROM; ram_mid_mapping.flags |= MEM_MAPPING_ROM;
else else
ram_mid_mapping.flags &= ~MEM_MAPPING_ROM; ram_mid_mapping.flags &= ~MEM_MAPPING_ROM;
#endif
break; break;
} }
ps2_mca_log("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS,cpu_state.pc, ps2.mem_regs[1],ps2.mem_regs[2]); ps2_mca_log("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS,cpu_state.pc, ps2.mem_regs[1],ps2.mem_regs[2]);

View File

@@ -8,7 +8,7 @@
* *
* Handling of the emulated machines. * Handling of the emulated machines.
* *
* Version: @(#)machine.h 1.0.26 2018/08/16 * Version: @(#)machine.h 1.0.27 2018/09/02
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -96,14 +96,11 @@ extern void machine_common_init(const machine_t *);
extern void machine_at_common_init(const machine_t *); extern void machine_at_common_init(const machine_t *);
extern void machine_at_init(const machine_t *); extern void machine_at_init(const machine_t *);
extern void machine_at_ibm_init(const machine_t *);
extern void machine_at_ps2_init(const machine_t *); extern void machine_at_ps2_init(const machine_t *);
extern void machine_at_common_ide_init(const machine_t *); extern void machine_at_common_ide_init(const machine_t *);
extern void machine_at_ide_init(const machine_t *); extern void machine_at_ide_init(const machine_t *);
extern void machine_at_ps2_ide_init(const machine_t *); extern void machine_at_ps2_ide_init(const machine_t *);
extern void machine_at_top_remap_init(const machine_t *);
extern void machine_at_ide_top_remap_init(const machine_t *);
extern void machine_at_ibm_init(const machine_t *);
extern void machine_at_t3100e_init(const machine_t *); extern void machine_at_t3100e_init(const machine_t *);

View File

@@ -11,7 +11,7 @@
* NOTES: OpenAT wip for 286-class machine with open BIOS. * NOTES: OpenAT wip for 286-class machine with open BIOS.
* PS2_M80-486 wip, pending receipt of TRM's for machine. * PS2_M80-486 wip, pending receipt of TRM's for machine.
* *
* Version: @(#)machine_table.c 1.0.33 2018/08/16 * Version: @(#)machine_table.c 1.0.35 2018/09/02
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -34,37 +34,37 @@
const machine_t machines[] = { const machine_t machines[] = {
{ "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
{ "[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, { "[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL },
{ "[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
{ "[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 32, 0, machine_xt_init, NULL }, { "[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 32, 0, machine_xt_init, NULL },
{ "[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, { "[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device },
{ "[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
{ "[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Generic XT clone", ROM_GENXT, "genxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
{ "[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
{ "[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL },
{ "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens",cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, { "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL },
{ "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device }, { "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device },
{ "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device }, { "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device },
{ "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device }, { "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device },
#if defined(DEV_BRANCH) && defined(USE_LASERXT) #if defined(DEV_BRANCH) && defined(USE_LASERXT)
{ "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL }, { "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"Intel", cpus_8088}, {"", NULL},, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL },
#endif #endif
{ "[8088] Xi8088", ROM_XI8088, "xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL }, { "[8088] Xi8088", ROM_XI8088, "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL },
{ "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL }, { "[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"Intel", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL }, { "[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL }, { "[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL }, { "[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 640, 640, 0, 63, machine_amstrad_init, NULL },
{ "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL }, { "[8086] Amstrad PC20(0)", ROM_PC200, "pc200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 512, 640, 128, 63, machine_amstrad_init, NULL },
{ "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL }, { "[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO | MACHINE_MOUSE, 128, 640, 128, 0, machine_olim24_init, NULL },
{ "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL }, { "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL },
{ "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, { "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device },
#if defined(DEV_BRANCH) && defined(USE_LASERXT) #if defined(DEV_BRANCH) && defined(USE_LASERXT)
{ "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL }, { "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_laserxt_init, NULL },
#endif #endif
{ "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_neat_ami_init, NULL }, { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,8192, 128, 127, machine_at_neat_ami_init, NULL },
{ "[286 ISA] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL }, { "[286 ISA] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_scat_init, NULL },
{ "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL },
{ "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_compaq_init, NULL }, { "[286 ISA] Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_compaq_init, NULL },
@@ -87,11 +87,11 @@ const machine_t machines[] = {
{ "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL }, { "[286 MCA] IBM PS/2 model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC_PS2 | MACHINE_VIDEO, 1, 10, 1, 63, machine_ps2_model_50_init, NULL },
{ "[386SX ISA] AMA-932J", ROM_AMA932J, "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_headland_init, at_ama932j_get_device }, { "[386SX ISA] AMA-932J", ROM_AMA932J, "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_headland_init, at_ama932j_get_device },
{ "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL }, { "[386SX ISA] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_headland_init, NULL },
{ "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL }, { "[386SX ISA] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC, 1, 16, 1, 127, machine_at_wd76c10_init, NULL },
{ "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, { "[386SX ISA] Award 386SX clone", ROM_AWARD386SX_OPTI495, "award386sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL },
{ "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_neat_init, NULL }, { "[386SX ISA] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,8192, 128, 127, machine_at_neat_init, NULL },
{ "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL }, { "[386SX ISA] IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 6, 1, 63, machine_ps1_m2121_init, NULL },
{ "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_scatsx_init, NULL }, { "[386SX ISA] KMX-C-02", ROM_KMXC02, "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 512, 127, machine_at_scatsx_init, NULL },
@@ -101,7 +101,7 @@ const machine_t machines[] = {
{ "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL }, { "[386DX ISA] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL },
{ "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL }, { "[386DX ISA] Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC | MACHINE_VIDEO, 1, 32, 1, 127, machine_at_wd76c10_init, NULL },
{ "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL }, { "[386DX ISA] Award 386DX clone", ROM_AWARD386DX_OPTI495, "award386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_init, NULL },
{ "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL }, { "[386DX ISA] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_opti495_ami_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_PORTABLE3) #if defined(DEV_BRANCH) && defined(USE_PORTABLE3)
{ "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL }, { "[386DX ISA] Compaq Portable III (386)", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC | MACHINE_VIDEO, 1, 14, 1, 127, machine_at_compaq_init, NULL },
#endif #endif

262
src/mem.c
View File

@@ -12,7 +12,7 @@
* the DYNAMIC_TABLES=1 enables this. Will eventually go * the DYNAMIC_TABLES=1 enables this. Will eventually go
* away, either way... * away, either way...
* *
* Version: @(#)mem.c 1.0.11 2018/08/20 * Version: @(#)mem.c 1.0.12 2018/09/02
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -71,19 +71,23 @@
#define DYNAMIC_TABLES 0 /* experimental */ #define DYNAMIC_TABLES 0 /* experimental */
mem_mapping_t ram_low_mapping; mem_mapping_t base_mapping,
mem_mapping_t ram_high_mapping; ram_low_mapping, /* 0..640K mapping */
mem_mapping_t ram_mid_mapping; #if 1
mem_mapping_t bios_mapping[8]; ram_mid_mapping,
mem_mapping_t bios_high_mapping[8]; #endif
mem_mapping_t romext_mapping; ram_remapped_mapping, /* 640..1024K mapping */
ram_high_mapping, /* 1024K+ mapping */
ram_remapped_mapping,
ram_split_mapping,
bios_mapping[8],
bios_high_mapping[8],
romext_mapping;
page_t *pages, /* RAM page table */ page_t *pages, /* RAM page table */
**page_lookup; /* pagetable lookup */ **page_lookup; /* pagetable lookup */
uint32_t pages_sz; /* #pages in table */ uint32_t pages_sz; /* #pages in table */
uint8_t isram[0x10000];
uint8_t *ram; /* the virtual RAM */ uint8_t *ram; /* the virtual RAM */
uint32_t rammask; uint32_t rammask;
@@ -139,9 +143,6 @@ static mem_mapping_t *_mem_mapping_r[0x40000];
static mem_mapping_t *_mem_mapping_w[0x40000]; static mem_mapping_t *_mem_mapping_w[0x40000];
static int _mem_state[0x40000]; static int _mem_state[0x40000];
static mem_mapping_t base_mapping;
static mem_mapping_t ram_remapped_mapping;
#if FIXME #if FIXME
static uint8_t ff_array[0x1000]; static uint8_t ff_array[0x1000];
#else #else
@@ -1359,7 +1360,7 @@ mem_mapping_write_allowed(uint32_t flags, int state)
static void static void
mem_mapping_recalc(uint64_t base, uint64_t size) mem_mapping_recalc(uint64_t base, uint64_t size)
{ {
mem_mapping_t *map = base_mapping.next; mem_mapping_t *map = base_mapping.next;
uint64_t c; uint64_t c;
@@ -1369,7 +1370,6 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
for (c = base; c < base + size; c += 0x4000) { for (c = base; c < base + size; c += 0x4000) {
_mem_read_b[c >> 14] = NULL; _mem_read_b[c >> 14] = NULL;
_mem_read_w[c >> 14] = NULL; _mem_read_w[c >> 14] = NULL;
_mem_read_l[c >> 14] = NULL;
_mem_read_l[c >> 14] = NULL; _mem_read_l[c >> 14] = NULL;
_mem_priv_r[c >> 14] = NULL; _mem_priv_r[c >> 14] = NULL;
_mem_mapping_r[c >> 14] = NULL; _mem_mapping_r[c >> 14] = NULL;
@@ -1380,38 +1380,38 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
_mem_mapping_w[c >> 14] = NULL; _mem_mapping_w[c >> 14] = NULL;
} }
/* Walk mapping list. */ /* Walk mapping list. */
while (map != NULL) { while (map != NULL) {
/*In range?*/ /*In range?*/
if (mapping->enable && (uint64_t)mapping->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)mapping->base + (uint64_t)mapping->size) > (uint64_t)base) { if (map->enable && (uint64_t)map->base < ((uint64_t)base + (uint64_t)size) && ((uint64_t)map->base + (uint64_t)map->size) > (uint64_t)base) {
uint64_t start = (mapping->base < base) ? mapping->base : base; uint64_t start = (map->base < base) ? map->base : base;
uint64_t end = (((uint64_t)mapping->base + (uint64_t)mapping->size) < (base + size)) ? ((uint64_t)mapping->base + (uint64_t)mapping->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 < mapping->base) if (start < map->base)
start = map->base; start = map->base;
for (c = start; c < end; c += 0x4000) { for (c = start; c < end; c += 0x4000) {
if ((mapping->read_b || mapping->read_w || mapping->read_l) && if ((map->read_b || map->read_w || map->read_l) &&
mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) { mem_mapping_read_allowed(map->flags, _mem_state[c >> 14])) {
_mem_read_b[c >> 14] = mapping->read_b; _mem_read_b[c >> 14] = map->read_b;
_mem_read_w[c >> 14] = mapping->read_w; _mem_read_w[c >> 14] = map->read_w;
_mem_read_l[c >> 14] = mapping->read_l; _mem_read_l[c >> 14] = map->read_l;
if (mapping->exec) if (map->exec)
_mem_exec[c >> 14] = map->exec + (c - map->base); _mem_exec[c >> 14] = map->exec + (c - map->base);
else else
_mem_exec[c >> 14] = NULL; _mem_exec[c >> 14] = NULL;
_mem_priv_r[c >> 14] = mapping->p; _mem_priv_r[c >> 14] = map->p;
_mem_mapping_r[c >> 14] = map; _mem_mapping_r[c >> 14] = map;
} }
if ((mapping->write_b || mapping->write_w || mapping->write_l) && if ((map->write_b || map->write_w || map->write_l) &&
mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) { mem_mapping_write_allowed(map->flags, _mem_state[c >> 14])) {
_mem_write_b[c >> 14] = mapping->write_b; _mem_write_b[c >> 14] = map->write_b;
_mem_write_w[c >> 14] = mapping->write_w; _mem_write_w[c >> 14] = map->write_w;
_mem_write_l[c >> 14] = mapping->write_l; _mem_write_l[c >> 14] = map->write_l;
_mem_priv_w[c >> 14] = mapping->p; _mem_priv_w[c >> 14] = map->p;
_mem_mapping_w[c >> 14] = map; _mem_mapping_w[c >> 14] = map;
} }
} }
} }
map = map->next; map = map->next;
} }
@@ -1419,7 +1419,24 @@ mem_mapping_recalc(uint64_t base, uint64_t size)
} }
void void
mem_mapping_del(mem_mapping_t *map)
{
mem_mapping_t *ptr;
/* Disable the entry. */
mem_mapping_disable(map);
/* Zap it from the list. */
for (ptr = &base_mapping; ptr->next != NULL; ptr = ptr->next) {
if (ptr->next == map) {
ptr->next = map->next;
break;
}
}
}
void
mem_mapping_add(mem_mapping_t *map, mem_mapping_add(mem_mapping_t *map,
uint32_t base, uint32_t base,
uint32_t size, uint32_t size,
@@ -1429,7 +1446,7 @@ mem_mapping_add(mem_mapping_t *mapping,
void (*write_b)(uint32_t addr, uint8_t val, 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_w)(uint32_t addr, uint16_t val, void *p),
void (*write_l)(uint32_t addr, uint32_t val, void *p), void (*write_l)(uint32_t addr, uint32_t val, void *p),
uint8_t *exec, uint8_t *exec,
uint32_t fl, uint32_t fl,
void *p) void *p)
{ {
@@ -1437,32 +1454,33 @@ mem_mapping_add(mem_mapping_t *mapping,
/* Add mapping to the end of the list.*/ /* Add mapping to the end of the list.*/
while (dest->next) while (dest->next)
dest = dest->next; dest = dest->next;
dest->next = mapping; dest->next = map;
map->prev = dest; map->prev = dest;
if (size) if (size)
map->enable = 1; map->enable = 1;
else else
mapping->enable = 0; map->enable = 0;
mapping->base = base; map->base = base;
mapping->size = size; map->size = size;
mapping->read_b = read_b; map->read_b = read_b;
mapping->read_w = read_w; map->read_w = read_w;
mapping->read_l = read_l; map->read_l = read_l;
mapping->write_b = write_b; map->write_b = write_b;
mapping->write_w = write_w; map->write_w = write_w;
mapping->write_l = write_l; map->write_l = write_l;
mapping->exec = exec; map->exec = exec;
mapping->flags = flags; map->flags = fl;
mapping->p = p; map->p = p;
map->dev = NULL;
map->next = NULL; map->next = NULL;
mem_mapping_recalc(map->base, map->size); mem_mapping_recalc(map->base, map->size);
} }
void void
mem_mapping_set_handler(mem_mapping_t *map, mem_mapping_set_handler(mem_mapping_t *map,
uint8_t (*read_b)(uint32_t addr, void *p), uint8_t (*read_b)(uint32_t addr, void *p),
uint16_t (*read_w)(uint32_t addr, void *p), uint16_t (*read_w)(uint32_t addr, void *p),
@@ -1470,64 +1488,71 @@ mem_mapping_set_handler(mem_mapping_t *mapping,
void (*write_b)(uint32_t addr, uint8_t val, 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_w)(uint32_t addr, uint16_t val, void *p),
void (*write_l)(uint32_t addr, uint32_t val, void *p)) void (*write_l)(uint32_t addr, uint32_t val, void *p))
{ {
mapping->read_b = read_b; map->read_b = read_b;
mapping->read_w = read_w; map->read_w = read_w;
mapping->read_l = read_l; map->read_l = read_l;
mapping->write_b = write_b; map->write_b = write_b;
mapping->write_w = write_w; map->write_w = write_w;
map->write_l = write_l; map->write_l = write_l;
mem_mapping_recalc(map->base, map->size); mem_mapping_recalc(map->base, map->size);
} }
void void
mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size)
{ {
/* Remove old mapping. */ /* Remove old mapping. */
mapping->enable = 0; map->enable = 0;
mem_mapping_recalc(map->base, map->size); mem_mapping_recalc(map->base, map->size);
/* Set new mapping. */ /* Set new mapping. */
mapping->enable = 1; map->enable = 1;
mapping->base = base; map->base = base;
map->size = size; map->size = size;
mem_mapping_recalc(map->base, map->size); mem_mapping_recalc(map->base, map->size);
} }
void void
mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec)
{ {
map->exec = exec; map->exec = exec;
mem_mapping_recalc(map->base, map->size); mem_mapping_recalc(map->base, map->size);
} }
void void
mem_mapping_set_p(mem_mapping_t *map, void *p) mem_mapping_set_p(mem_mapping_t *map, void *p)
{ {
map->p = p; map->p = p;
} }
void void
mem_mapping_set_dev(mem_mapping_t *map, void *p) mem_mapping_set_dev(mem_mapping_t *map, void *p)
{ {
mapping->enable = 0;
map->dev = p; map->dev = p;
} }
void void
mem_mapping_disable(mem_mapping_t *map) mem_mapping_disable(mem_mapping_t *map)
{ {
map->enable = 0; map->enable = 0;
mem_mapping_recalc(map->base, map->size);
}
void
mem_mapping_enable(mem_mapping_t *map)
{
map->enable = 1;
mem_mapping_recalc(map->base, map->size); mem_mapping_recalc(map->base, map->size);
} }
@@ -1754,15 +1779,6 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
pages[c].write_w = mem_write_ramw_page; pages[c].write_w = mem_write_ramw_page;
pages[c].write_l = mem_write_raml_page; pages[c].write_l = mem_write_raml_page;
} }
}
/* Initialize the tables. */
memset(isram, 0x00, sizeof(isram));
for (c = 0; c < (mem_size / 64); c++) {
isram[c] = 1;
if ((c >= 0xa && c <= 0xf) ||
(cpu_16bitbus && c >= 0xfe && c <= 0xff))
isram[c] = 0;
} }
memset(_mem_read_b, 0x00, sizeof(_mem_read_b)); memset(_mem_read_b, 0x00, sizeof(_mem_read_b));
@@ -1811,18 +1827,18 @@ mem_log("MEM: reset: new pages=%08lx, pages_sz=%i\n", pages, pages_sz);
if (mem_size > 768) if (mem_size > 768)
mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000,
mem_read_ram,mem_read_ramw,mem_read_raml, mem_read_ram,mem_read_ramw,mem_read_raml,
mem_write_ram,mem_write_ramw,mem_write_raml, mem_write_ram,mem_write_ramw,mem_write_raml,
ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL);
if (romset == ROM_IBMPS1_2011) if (romset == ROM_IBMPS1_2011)
mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_mapping_add(&romext_mapping, 0xc8000, 0x08000,
mem_read_romext,mem_read_romextw,mem_read_romextl, mem_read_romext,mem_read_romextw,mem_read_romextl,
NULL,NULL, NULL, romext, 0, NULL); NULL,NULL, NULL, romext, 0, NULL);
mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024,
mem_read_remapped, mem_read_remappedw, mem_read_remappedl, mem_read_remapped,mem_read_remappedw,mem_read_remappedl,
mem_write_remapped, mem_write_remappedw, mem_write_remappedl, mem_write_remapped,mem_write_remappedw,mem_write_remappedl,
ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL);
mem_mapping_disable(&ram_remapped_mapping); mem_mapping_disable(&ram_remapped_mapping);
mem_a20_init(); mem_a20_init();
@@ -1858,45 +1874,33 @@ mem_init(void)
/* Reset the memory state. */ /* Reset the memory state. */
mem_reset(); mem_reset();
} }
void void
mem_remap_top(int max_size) mem_remap_top(int kb)
{
uint32_t start = (mem_size >= 1024) ? mem_size : 1024; uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
uint32_t c; int size = mem_size - 640;
if (mem_size > 640) {
uint32_t start = (mem_size >= 1024) ? mem_size : 1024;
int size = mem_size - 640;
pclog("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); pclog("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size);
size = max_size; if (mem_size <= 640) return;
if (kb == 0) {
/* Called to disable the mapping. */ /* Called to disable the mapping. */
isram[c] = 1; mem_mapping_disable(&ram_remapped_mapping);
mem_set_mem_state(start * 1024, size * 1024, return;
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); }
if (size > kb)
size = kb;
mem_set_mem_state(start * 1024, size * 1024,
MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024);
mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024)); mem_mapping_set_exec(&ram_remapped_mapping, ram + (start * 1024));
flushmmucache(); flushmmucache();
}
void
mem_remap_top_256k(void)
{
mem_remap_top(256);
}
void
mem_remap_top_384k(void)
{
mem_remap_top(384);
}
} }
void void

View File

@@ -8,7 +8,7 @@
* *
* Definitions for the memory interface. * Definitions for the memory interface.
* *
* Version: @(#)mem.h 1.0.4 2018/03/16 * Version: @(#)mem.h 1.0.5 2018/09/02
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * Sarah Walker, <tommowalker@tommowalker.co.uk>
@@ -77,7 +77,9 @@ typedef struct _mem_mapping_ {
uint32_t flags; uint32_t flags;
void *p; void *p; /* backpointer to mapping or device */
void *dev; /* backpointer to memory device */
} mem_mapping_t; } mem_mapping_t;
typedef struct _page_ { typedef struct _page_ {
@@ -114,12 +116,16 @@ extern uintptr_t *writelookup2;
extern int writelnext; extern int writelnext;
extern uint32_t ram_mapped_addr[64]; extern uint32_t ram_mapped_addr[64];
extern mem_mapping_t bios_mapping[8], mem_mapping_t base_mapping,
bios_high_mapping[8],
romext_mapping,
ram_low_mapping, ram_low_mapping,
#if 1
ram_mid_mapping, ram_mid_mapping,
ram_high_mapping; #endif
ram_remapped_mapping,
ram_high_mapping,
bios_mapping[8],
bios_high_mapping[8],
romext_mapping;
extern uint32_t mem_logical_addr; extern uint32_t mem_logical_addr;
@@ -135,7 +141,6 @@ extern int readlnum,
extern int nopageerrors; extern int nopageerrors;
extern int memspeed[11]; extern int memspeed[11];
extern uint8_t isram[0x10000];
extern int mmu_perm; extern int mmu_perm;
@@ -165,7 +170,10 @@ extern uint32_t mmutranslatereal(uint32_t addr, int rw);
extern void addreadlookup(uint32_t virt, uint32_t phys); extern void addreadlookup(uint32_t virt, uint32_t phys);
extern void addwritelookup(uint32_t virt, uint32_t phys); extern void addwritelookup(uint32_t virt, uint32_t phys);
extern void mem_mapping_add(mem_mapping_t *mapping,
extern void mem_mapping_del(mem_mapping_t *);
extern void mem_mapping_add(mem_mapping_t *,
uint32_t base, uint32_t base,
uint32_t size, uint32_t size,
uint8_t (*read_b)(uint32_t addr, void *p), uint8_t (*read_b)(uint32_t addr, void *p),
@@ -178,7 +186,7 @@ extern void mem_mapping_add(mem_mapping_t *mapping,
uint32_t flags, uint32_t flags,
void *p); void *p);
extern void mem_mapping_set_handler(mem_mapping_t *mapping, extern void mem_mapping_set_handler(mem_mapping_t *,
uint8_t (*read_b)(uint32_t addr, void *p), uint8_t (*read_b)(uint32_t addr, void *p),
uint16_t (*read_w)(uint32_t addr, void *p), uint16_t (*read_w)(uint32_t addr, void *p),
uint32_t (*read_l)(uint32_t addr, void *p), uint32_t (*read_l)(uint32_t addr, void *p),
@@ -186,22 +194,26 @@ extern void mem_mapping_set_handler(mem_mapping_t *mapping,
void (*write_w)(uint32_t addr, uint16_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)); void (*write_l)(uint32_t addr, uint32_t val, void *p));
extern void mem_mapping_set_p(mem_mapping_t *mapping, void *p); extern void mem_mapping_set_p(mem_mapping_t *, void *p);
extern void mem_mapping_set_addr(mem_mapping_t *mapping, 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); uint32_t base, uint32_t size);
extern void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec); extern void mem_mapping_set_exec(mem_mapping_t *, uint8_t *exec);
extern void mem_mapping_disable(mem_mapping_t *mapping); extern void mem_mapping_disable(mem_mapping_t *);
extern void mem_mapping_enable(mem_mapping_t *mapping); extern void mem_mapping_enable(mem_mapping_t *);
extern void mem_set_mem_state(uint32_t base, uint32_t size, int state); extern void mem_set_mem_state(uint32_t base, uint32_t size, int state);
extern uint8_t mem_readb_phys(uint32_t addr); extern uint8_t mem_readb_phys(uint32_t addr);
extern uint8_t mem_readb_phys_dma(uint32_t addr); extern uint8_t mem_readb_phys_dma(uint32_t addr);
extern uint16_t mem_readw_phys(uint32_t addr); extern uint16_t mem_readw_phys(uint32_t addr);
extern uint32_t mem_readl_phys(uint32_t addr);
extern void mem_writeb_phys(uint32_t addr, uint8_t val); extern void mem_writeb_phys(uint32_t addr, uint8_t val);
extern void mem_writeb_phys_dma(uint32_t addr, uint8_t val); extern void mem_writeb_phys_dma(uint32_t addr, uint8_t val);
extern void mem_writew_phys(uint32_t addr, uint16_t val); extern void mem_writew_phys(uint32_t addr, uint16_t val);
extern void mem_writel_phys(uint32_t addr, uint32_t val);
extern uint8_t mem_read_ram(uint32_t addr, void *priv); extern uint8_t mem_read_ram(uint32_t addr, void *priv);
extern uint16_t mem_read_ramw(uint32_t addr, void *priv); extern uint16_t mem_read_ramw(uint32_t addr, void *priv);
@@ -240,8 +252,7 @@ extern void mem_add_bios(void);
extern void mem_init(void); extern void mem_init(void);
extern void mem_reset(void); extern void mem_reset(void);
extern void mem_remap_top_256k(void); extern void mem_remap_top(int kb);
extern void mem_remap_top_384k(void);
extern uint8_t port_92_read(uint16_t port, void *priv); extern uint8_t port_92_read(uint16_t port, void *priv);
extern void port_92_write(uint16_t port, uint8_t val, void *priv); extern void port_92_write(uint16_t port, uint8_t val, void *priv);

View File

@@ -8,7 +8,7 @@
* *
* Main emulator module where most things are controlled. * Main emulator module where most things are controlled.
* *
* Version: @(#)pc.c 1.0.75 2018/08/16 * Version: @(#)pc.c 1.0.76 2018/09/02
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -47,6 +47,8 @@
#include "nvr.h" #include "nvr.h"
#include "machine/machine.h" #include "machine/machine.h"
#include "bugger.h" #include "bugger.h"
#include "isamem.h"
#include "isartc.h"
#include "lpt.h" #include "lpt.h"
#include "serial.h" #include "serial.h"
#include "keyboard.h" #include "keyboard.h"
@@ -107,7 +109,9 @@ int vid_cga_contrast = 0, /* (C) video */
force_43 = 0; /* (C) video */ force_43 = 0; /* (C) video */
int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */ int serial_enabled[SERIAL_MAX] = {0,0}, /* (C) enable serial ports */
lpt_enabled = 0, /* (C) enable LPT ports */ lpt_enabled = 0, /* (C) enable LPT ports */
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 */
isartc_type = 0; /* (C) enable ISA RTC card */
int gfxcard = 0; /* (C) graphics/video card */ int gfxcard = 0; /* (C) graphics/video card */
int sound_is_float = 1, /* (C) sound uses FP values */ int sound_is_float = 1, /* (C) sound uses FP values */
GAMEBLASTER = 0, /* (C) sound option */ GAMEBLASTER = 0, /* (C) sound option */
@@ -769,6 +773,12 @@ pc_reset_hard_init(void)
video_font_reset(); /* Reset (deallocate) the video font arrays. */ video_font_reset(); /* Reset (deallocate) the video font arrays. */
machine_init(); machine_init();
/* Reset any ISA memory cards. */
isamem_reset();
/* Reset any ISA RTC cards. */
isartc_reset();
fdd_reset(); fdd_reset();
/* /*

View File

@@ -30,6 +30,7 @@
#include "../86box.h" #include "../86box.h"
#include "../device.h" #include "../device.h"
#include "../io.h" #include "../io.h"
#include "../mca.h"
#include "../pic.h" #include "../pic.h"
#include "../timer.h" #include "../timer.h"
#include "sound.h" #include "sound.h"
@@ -73,6 +74,7 @@ mpu401_log(const char *fmt, ...)
#endif #endif
} }
int mca_version = 0;
static void static void
QueueByte(mpu_t *mpu, uint8_t data) QueueByte(mpu_t *mpu, uint8_t data)
@@ -827,7 +829,7 @@ MPU401_Event(void *priv)
next_event: next_event:
/* mpu401_event_callback = 0LL; */ /* mpu401_event_callback = 0LL; */
new_time = ((mpu->clock.tempo * mpu->clock.timebase * mpu->clock.tempo_rel)/0x40); new_time = ((mpu->clock.tempo * mpu->clock.timebase * mpu->clock.tempo_rel)/0x40);
if (new_time == 0) { if (new_time == 0) {
mpu401_event_callback = 0LL; mpu401_event_callback = 0LL;
return; return;
} else { } else {
@@ -873,11 +875,52 @@ mpu401_device_add(void)
if (!mpu401_standalone_enable) return; if (!mpu401_standalone_enable) return;
n = sound_card_get_internal_name(sound_card_current); n = sound_card_get_internal_name(sound_card_current);
if (n != NULL) { if (n != NULL)
if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) return; {
if (!strcmp(n, "ncraudio"))
mca_version = 1;
else
mca_version = 0;
if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32") || !strcmp(n, "replysb16")) return;
} }
device_add(&mpu401_device); if (mca_version)
device_add(&mpu401_mca_device);
else
device_add(&mpu401_device);
}
static uint8_t mpu401_mca_read(int port, void *p)
{
mpu_t *mpu = (mpu_t *)p;
return mpu->pos_regs[port & 7];
}
static void mpu401_mca_write(int port, uint8_t val, void *p)
{
mpu_t *mpu = (mpu_t *)p;
uint16_t addr;
if (port < 0x102)
return;
addr = (mpu->pos_regs[2] & 2) ? 0x0330 : 0x1330;
io_removehandler(addr, 2,
mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu);
io_removehandler(0x2A20, 16,
NULL, NULL, NULL, imf_write, NULL, NULL, mpu);
mpu->pos_regs[port & 7] = val;
if (mpu->pos_regs[2] & 1)
{
addr = (mpu->pos_regs[2] & 2) ? 0x0330 : 0x1330;
mpu401_init(mpu, addr, device_get_config_int("irq"), device_get_config_int("mode"));
}
} }
@@ -890,9 +933,17 @@ mpu401_standalone_init(const device_t *info)
memset(mpu, 0, sizeof(mpu_t)); memset(mpu, 0, sizeof(mpu_t));
mpu401_log("mpu_init\n"); mpu401_log("mpu_init\n");
mpu401_init(mpu, device_get_config_hex16("base"), device_get_config_int("irq"), device_get_config_int("mode"));
if (info->flags & DEVICE_MCA)
{
mca_add(mpu401_mca_read, mpu401_mca_write, mpu);
mpu->pos_regs[0] = 0x0F;
mpu->pos_regs[1] = 0x6C;
}
else
mpu401_init(mpu, device_get_config_hex16("base"), device_get_config_int("irq"), device_get_config_int("mode"));
return(mpu); return(mpu);
} }
@@ -967,12 +1018,69 @@ static const device_config_t mpu401_standalone_config[] =
}; };
static const device_config_t mpu401_mca_standalone_config[] =
{
{
"irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 9,
{
{
"IRQ 9", 9
},
{
"IRQ 3", 3
},
{
"IRQ 4", 4
},
{
"IRQ 5", 5
},
{
"IRQ 7", 7
},
{
"IRQ 10", 10
},
{
""
}
}
},
{
"mode", "Mode", CONFIG_SELECTION, "", 1,
{
{
"UART", M_UART
},
{
"Intelligent", M_INTELLIGENT
},
{
""
}
}
},
{
"", "", -1
}
};
const device_t mpu401_device = { const device_t mpu401_device = {
"MPU-401 (Standalone)", "MPU-401 (Standalone)",
0, 0, DEVICE_ISA, 0,
mpu401_standalone_init, mpu401_standalone_close, NULL, mpu401_standalone_init, mpu401_standalone_close, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
mpu401_standalone_config mpu401_standalone_config
}; };
const device_t mpu401_mca_device = {
"MPU-401 MCA (Standalone)",
DEVICE_MCA, 0,
mpu401_standalone_init, mpu401_standalone_close, NULL,
NULL,
NULL,
NULL,
mpu401_mca_standalone_config
};

View File

@@ -80,15 +80,18 @@ typedef struct mpu_t
uint8_t cth_rate,cth_counter; uint8_t cth_rate,cth_counter;
int clock_to_host,cth_active; int clock_to_host,cth_active;
} clock; } clock;
uint8_t pos_regs[8];
} mpu_t; } mpu_t;
uint8_t MPU401_ReadData(mpu_t *mpu); uint8_t MPU401_ReadData(mpu_t *mpu);
void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode);
extern int mca_version;
extern int mpu401_standalone_enable; extern int mpu401_standalone_enable;
void mpu401_device_add(void); void mpu401_device_add(void);
const device_t mpu401_device; const device_t mpu401_device;
const device_t mpu401_mca_device;
void mpu401_uart_init(mpu_t *mpu, uint16_t addr);

View File

@@ -38,6 +38,7 @@
#include "vid_ati_eeprom.h" #include "vid_ati_eeprom.h"
#include "vid_svga.h" #include "vid_svga.h"
#include "vid_svga_render.h" #include "vid_svga_render.h"
#include "vid_sc1502x_ramdac.h"
#define BIOS_ATIKOR_PATH L"roms/video/ati28800/atikorvga.bin" #define BIOS_ATIKOR_PATH L"roms/video/ati28800/atikorvga.bin"
@@ -58,6 +59,7 @@ typedef struct ati28800_t
{ {
svga_t svga; svga_t svga;
ati_eeprom_t eeprom; ati_eeprom_t eeprom;
sc1502x_ramdac_t ramdac;
rom_t bios_rom; rom_t bios_rom;
@@ -65,6 +67,7 @@ typedef struct ati28800_t
int index; int index;
uint32_t memory; uint32_t memory;
uint8_t id;
uint8_t port_03dd_val; uint8_t port_03dd_val;
uint16_t get_korean_font_kind; uint16_t get_korean_font_kind;
@@ -95,6 +98,7 @@ ati28800_log(const char *fmt, ...)
#endif #endif
} }
static void ati28800_recalctimings(svga_t *svga);
static void ati28800_out(uint16_t addr, uint8_t val, void *p) static void ati28800_out(uint16_t addr, uint8_t val, void *p)
{ {
@@ -115,25 +119,43 @@ static void ati28800_out(uint16_t addr, uint8_t val, void *p)
case 0x1cf: case 0x1cf:
old=ati28800->regs[ati28800->index]; old=ati28800->regs[ati28800->index];
ati28800->regs[ati28800->index] = val; ati28800->regs[ati28800->index] = val;
pclog("ATI write reg=%02x\n", ati28800->index);
switch (ati28800->index) switch (ati28800->index)
{ {
case 0xb2: case 0xb2:
case 0xbe: case 0xbe:
case 0xbd:
if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/
{ {
svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000; if (ati28800->regs[0xbd] & 4)
svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; {
svga->read_bank = (((ati28800->regs[0xb2] >> 5) & 7) * 0x20000);
svga->write_bank = (((ati28800->regs[0xb2] >> 1) & 7) * 0x20000);
}
else
{
svga->read_bank = (((ati28800->regs[0xb2] >> 5) & 7) * 0x10000);
svga->write_bank = (((ati28800->regs[0xb2] >> 1) & 7) * 0x10000);
}
} }
else /*Single bank mode*/ else /*Single bank mode*/
svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; {
if (ati28800->regs[0xbd] & 4)
{
svga->read_bank = (((ati28800->regs[0xb2] >> 1) & 7) * 0x20000);
svga->write_bank = (((ati28800->regs[0xb2] >> 1) & 7) * 0x20000);
}
else
{
svga->read_bank = (((ati28800->regs[0xb2] >> 1) & 7) * 0x10000);
svga->write_bank = (((ati28800->regs[0xb2] >> 1) & 7) * 0x10000);
}
}
break; break;
case 0xb3: case 0xb3:
ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1);
break; break;
case 0xb6: case 0xb6:
if (val & 1)
pclog("Extended 0xB6 bit 0 enabled\n");
if((old ^ val) & 0x10) svga_recalctimings(svga); if((old ^ val) & 0x10) svga_recalctimings(svga);
break; break;
case 0xb8: case 0xb8:
@@ -141,9 +163,14 @@ static void ati28800_out(uint16_t addr, uint8_t val, void *p)
break; break;
case 0xb9: case 0xb9:
if((old ^ val) & 2) svga_recalctimings(svga); if((old ^ val) & 2) svga_recalctimings(svga);
break;
} }
break; break;
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
sc1502x_ramdac_out(addr, val, &ati28800->ramdac, svga);
return;
case 0x3D4: case 0x3D4:
svga->crtcreg = val & 0x3f; svga->crtcreg = val & 0x3f;
return; return;
@@ -250,15 +277,20 @@ static uint8_t ati28800_in(uint16_t addr, void *p)
case 0x1cf: case 0x1cf:
switch (ati28800->index) switch (ati28800->index)
{ {
case 0xb0: case 0xaa:
if (ati28800->memory == 256) temp = ati28800->id;
return 0x08;
else if (ati28800->memory == 512)
return 0x10;
else
return 0x18;
break; break;
case 0xb0:
if (ati28800->memory == 1024)
temp = 0x08;
else if (ati28800->memory == 512)
temp = 0x10;
else
temp = 0x00;
ati28800->regs[0xb0] |= temp;
break;
case 0xb7: case 0xb7:
temp = ati28800->regs[ati28800->index] & ~8; temp = ati28800->regs[ati28800->index] & ~8;
if (ati_eeprom_read(&ati28800->eeprom)) if (ati_eeprom_read(&ati28800->eeprom))
@@ -277,6 +309,10 @@ static uint8_t ati28800_in(uint16_t addr, void *p)
else else
temp = 0x10; temp = 0x10;
break; break;
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
return sc1502x_ramdac_in(addr, &ati28800->ramdac, svga);
case 0x3D4: case 0x3D4:
temp = svga->crtcreg; temp = svga->crtcreg;
break; break;
@@ -359,12 +395,12 @@ static void ati28800_recalctimings(svga_t *svga)
if(ati28800->regs[0xb8] & 0x40) svga->clock *= 2; if(ati28800->regs[0xb8] & 0x40) svga->clock *= 2;
if (ati28800->regs[0xb6] & 0x10) if (ati28800->regs[0xb6] & 0x10)
{ {
svga->hdisp <<= 1; svga->hdisp <<= 1;
svga->htotal <<= 1; svga->htotal <<= 1;
svga->rowoffset <<= 1; svga->rowoffset <<= 1;
} }
if(svga->crtc[0x17] & 4) if(svga->crtc[0x17] & 4)
{ {
@@ -377,10 +413,21 @@ static void ati28800_recalctimings(svga_t *svga)
if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/
{ {
svga->render = svga_render_8bpp_highres; switch (svga->bpp)
svga->bpp = 8; {
svga->rowoffset <<= 1; case 8:
svga->ma <<= 1; svga->render = svga_render_8bpp_highres;
svga->rowoffset <<= 1;
svga->ma <<= 1;
break;
case 15:
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
svga->rowoffset <<= 1;
svga->ma <<= 1;
break;
}
} }
} }
@@ -435,15 +482,16 @@ ati28800k_init(const device_t *info)
static void * static void *
ati28800_init(const device_t *info) ati28800_init(const device_t *info)
{ {
ati28800_t *ati; ati28800_t *ati28800;
ati = malloc(sizeof(ati28800_t)); ati28800 = malloc(sizeof(ati28800_t));
memset(ati, 0x00, sizeof(ati28800_t)); memset(ati28800, 0x00, sizeof(ati28800_t));
ati->memory = device_get_config_int("memory"); ati28800->memory = device_get_config_int("memory");
switch(info->local) { switch(info->local) {
case GFX_VGAWONDERXL: case GFX_VGAWONDERXL:
rom_init_interleaved(&ati->bios_rom, ati28800->id = 6;
rom_init_interleaved(&ati28800->bios_rom,
BIOS_VGAXL_EVEN_PATH, BIOS_VGAXL_EVEN_PATH,
BIOS_VGAXL_ODD_PATH, BIOS_VGAXL_ODD_PATH,
0xc0000, 0x10000, 0xffff, 0xc0000, 0x10000, 0xffff,
@@ -452,7 +500,8 @@ ati28800_init(const device_t *info)
#if defined(DEV_BRANCH) && defined(USE_XL24) #if defined(DEV_BRANCH) && defined(USE_XL24)
case GFX_VGAWONDERXL24: case GFX_VGAWONDERXL24:
rom_init_interleaved(&ati->bios_rom, ati28800->id = 6;
rom_init_interleaved(&ati28800->bios_rom,
BIOS_XL24_EVEN_PATH, BIOS_XL24_EVEN_PATH,
BIOS_XL24_ODD_PATH, BIOS_XL24_ODD_PATH,
0xc0000, 0x10000, 0xffff, 0xc0000, 0x10000, 0xffff,
@@ -461,47 +510,48 @@ ati28800_init(const device_t *info)
#endif #endif
default: default:
rom_init(&ati->bios_rom, ati28800->id = 5;
rom_init(&ati28800->bios_rom,
BIOS_ROM_PATH, BIOS_ROM_PATH,
0xc0000, 0x8000, 0x7fff, 0xc0000, 0x8000, 0x7fff,
0, MEM_MAPPING_EXTERNAL); 0, MEM_MAPPING_EXTERNAL);
break; break;
} }
svga_init(&ati->svga, ati, ati->memory << 10, /*default: 512kb*/ svga_init(&ati28800->svga, ati28800, ati28800->memory << 10, /*default: 512kb*/
ati28800_recalctimings, ati28800_recalctimings,
ati28800_in, ati28800_out, ati28800_in, ati28800_out,
NULL, NULL,
NULL); NULL);
io_sethandler(0x01ce, 2, io_sethandler(0x01ce, 2,
ati28800_in, NULL, NULL, ati28800_in, NULL, NULL,
ati28800_out, NULL, NULL, ati); ati28800_out, NULL, NULL, ati28800);
io_sethandler(0x03c0, 32, io_sethandler(0x03c0, 32,
ati28800_in, NULL, NULL, ati28800_in, NULL, NULL,
ati28800_out, NULL, NULL, ati); ati28800_out, NULL, NULL, ati28800);
ati->svga.miscout = 1; ati28800->svga.miscout = 1;
switch (info->local) switch (info->local)
{ {
case GFX_VGAWONDERXL: case GFX_VGAWONDERXL:
ati_eeprom_load(&ati->eeprom, L"ati28800xl.nvr", 0); ati_eeprom_load(&ati28800->eeprom, L"ati28800xl.nvr", 0);
break; break;
#if defined(DEV_BRANCH) && defined(USE_XL24) #if defined(DEV_BRANCH) && defined(USE_XL24)
case GFX_VGAWONDERXL24: case GFX_VGAWONDERXL24:
ati_eeprom_load(&ati->eeprom, L"ati28800xl24.nvr", 0); ati_eeprom_load(&ati28800->eeprom, L"ati28800xl24.nvr", 0);
break; break;
#endif #endif
default: default:
ati_eeprom_load(&ati->eeprom, L"ati28800.nvr", 0); ati_eeprom_load(&ati28800->eeprom, L"ati28800.nvr", 0);
break; break;
} }
return(ati); return(ati28800);
} }
@@ -538,11 +588,11 @@ ati28800_wonderxl24_available(void)
static void static void
ati28800_close(void *priv) ati28800_close(void *priv)
{ {
ati28800_t *ati = (ati28800_t *)priv; ati28800_t *ati28800 = (ati28800_t *)priv;
svga_close(&ati->svga); svga_close(&ati28800->svga);
free(ati); free(ati28800);
} }
@@ -558,9 +608,9 @@ ati28800_speed_changed(void *p)
static void static void
ati28800_force_redraw(void *priv) ati28800_force_redraw(void *priv)
{ {
ati28800_t *ati = (ati28800_t *)priv; ati28800_t *ati28800 = (ati28800_t *)priv;
ati->svga.fullchange = changeframecount; ati28800->svga.fullchange = changeframecount;
} }

View File

@@ -8,7 +8,7 @@
* *
* Define all known video cards. * Define all known video cards.
* *
* Version: @(#)vid_table.c 1.0.33 2018/08/16 * Version: @(#)vid_table.c 1.0.35 2018/09/02
* *
* Authors: Miran Grca, <mgrca8@gmail.com> * Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
@@ -62,6 +62,7 @@
enum { enum {
VIDEO_ISA = 0, VIDEO_ISA = 0,
VIDEO_MCA,
VIDEO_BUS VIDEO_BUS
}; };
@@ -84,7 +85,7 @@ static const VIDEO_CARD
video_cards[] = { video_cards[] = {
{ "None", "none", NULL, GFX_NONE }, { "None", "none", NULL, GFX_NONE },
{ "Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, { "Internal", "internal", NULL, GFX_INTERNAL, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{ "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, { "[ISA] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_isa", &mach64gx_isa_device, GFX_MACH64GX_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
{ "[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, { "[ISA] ATI Korean VGA (ATI-28800-5)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
{ "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, { "[ISA] ATI VGA-88 (ATI-18800-1)", "ati18800v", &ati18800_vga88_device, GFX_VGA88, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{ "[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, { "[ISA] ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
@@ -125,7 +126,7 @@ video_cards[] = {
{"[ISA] Tseng ET4000AX", "et4000ax", &et4000_isa_device, GFX_ET4000_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"[ISA] Tseng ET4000AX", "et4000ax", &et4000_isa_device, GFX_ET4000_ISA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}},
{"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"[ISA] VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"[ISA] Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}},
{"[MCA] Tseng ET4000AX", "et4000mca", &et4000_mca_device, GFX_ET4000_MCA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 3, 6, 5, 5, 10}}, {"[MCA] Tseng ET4000AX", "et4000mca", &et4000_mca_device, GFX_ET4000_MCA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_MCA, 4, 5, 10, 5, 5, 10}},
{"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, GFX_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, GFX_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
{"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}},
{"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, GFX_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, GFX_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}},

View File

@@ -8,7 +8,7 @@
* *
* Application resource script for Windows. * Application resource script for Windows.
* *
* Version: @(#)86Box.rc 1.0.40 2018/08/04 * Version: @(#)86Box.rc 1.0.41 2018/09/02
* *
* Authors: Miran Grca, <mgrca8@gmail.com> * Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
@@ -434,7 +434,7 @@ BEGIN
BS_AUTOCHECKBOX | WS_TABSTOP,7,82,94,10 BS_AUTOCHECKBOX | WS_TABSTOP,7,82,94,10
END END
DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 97 DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 200
STYLE DS_CONTROL | WS_CHILD STYLE DS_CONTROL | WS_CHILD
FONT 9, "Segoe UI" FONT 9, "Segoe UI"
BEGIN BEGIN
@@ -458,6 +458,29 @@ BEGIN
CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button", CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10
LTEXT "ISA RTC",IDT_1767,7,99,61,10
COMBOBOX IDC_COMBO_ISARTC,71,98,140,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_ISARTC,214,98,46,12
GROUPBOX "ISA Memory Expansion",IDC_GROUP_ISAMEM,7,118,255,70
LTEXT "#1:",IDT_1763,12,130,21,10
COMBOBOX IDC_COMBO_ISAMEM_1,25,129,180,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_1,209,129,46,12
LTEXT "#2:",IDT_1764,12,144,21,10
COMBOBOX IDC_COMBO_ISAMEM_2,25,143,180,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_2,209,143,46,12
LTEXT "#3:",IDT_1765,12,158,21,10
COMBOBOX IDC_COMBO_ISAMEM_3,25,157,180,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_3,209,157,46,12
LTEXT "#4:",IDT_1766,12,172,21,10
COMBOBOX IDC_COMBO_ISAMEM_4,25,171,180,120,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Configure",IDC_CONFIGURE_ISAMEM_4,209,171,46,12
END END
DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154

View File

@@ -8,7 +8,7 @@
# #
# Makefile for Win32 (MinGW32) environment. # Makefile for Win32 (MinGW32) environment.
# #
# Version: @(#)Makefile.mingw 1.0.122 2018/08/01 # Version: @(#)Makefile.mingw 1.0.123 2018/09/02
# #
# Authors: Miran Grca, <mgrca8@gmail.com> # Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com> # Fred N. van Kempen, <decwiz@yahoo.com>
@@ -70,7 +70,7 @@ ifeq ($(DEV_BUILD), y)
endif endif
else else
ifndef DEBUG ifndef DEBUG
DEBUG := n DEBUG := y
endif endif
ifndef DEV_BRANCH ifndef DEV_BRANCH
DEV_BRANCH := n DEV_BRANCH := n
@@ -443,7 +443,7 @@ MCHOBJ := machine.o machine_table.o \
m_at_sis_85c471.o m_at_sis_85c496.o \ m_at_sis_85c471.o m_at_sis_85c496.o \
m_at_4x0.o m_at_4x0.o
DEVOBJ := bugger.o lpt.o $(SERIAL) \ DEVOBJ := bugger.o isamem.o isartc.o lpt.o $(SERIAL) \
sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \ sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \
sio_pc87306.o sio_w83877f.o sio_um8669f.o \ sio_pc87306.o sio_w83877f.o sio_um8669f.o \
keyboard.o \ keyboard.o \

View File

@@ -8,7 +8,7 @@
* *
* Windows resource defines. * Windows resource defines.
* *
* Version: @(#)resource.h 1.0.27 2018/08/04 * Version: @(#)resource.h 1.0.28 2018/09/02
* *
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/> * Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -92,6 +92,11 @@
#define IDT_1757 1757 /* Progress: */ #define IDT_1757 1757 /* Progress: */
#define IDT_1758 1758 /* Speed: */ #define IDT_1758 1758 /* Speed: */
#define IDT_1759 1759 /* ZIP drives: */ #define IDT_1759 1759 /* 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_1767 1767 /* ISA RTC: */
/* /*
@@ -166,69 +171,81 @@
#define IDC_CHECK_IDE_QUA 1127 #define IDC_CHECK_IDE_QUA 1127
#define IDC_BUTTON_IDE_QUA 1128 #define IDC_BUTTON_IDE_QUA 1128
#define IDC_CHECK_BUGGER 1129 #define IDC_CHECK_BUGGER 1129
#define IDC_CONFIGURE_BUGGER 1130
#define IDC_COMBO_ISARTC 1131
#define IDC_CONFIGURE_ISARTC 1132
#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_HARD_DISKS 1130 /* hard disk config */ #define IDC_HARD_DISKS 1150 /* hard disk config */
#define IDC_LIST_HARD_DISKS 1131 #define IDC_LIST_HARD_DISKS 1151
#define IDC_BUTTON_HDD_ADD_NEW 1132 #define IDC_BUTTON_HDD_ADD_NEW 1152
#define IDC_BUTTON_HDD_ADD 1133 #define IDC_BUTTON_HDD_ADD 1153
#define IDC_BUTTON_HDD_REMOVE 1134 #define IDC_BUTTON_HDD_REMOVE 1154
#define IDC_COMBO_HD_BUS 1135 #define IDC_COMBO_HD_BUS 1155
#define IDC_COMBO_HD_CHANNEL 1136 #define IDC_COMBO_HD_CHANNEL 1156
#define IDC_COMBO_HD_ID 1137 #define IDC_COMBO_HD_ID 1157
#define IDC_COMBO_HD_LUN 1138 #define IDC_COMBO_HD_LUN 1158
#define IDC_COMBO_HD_CHANNEL_IDE 1139 #define IDC_COMBO_HD_CHANNEL_IDE 1159
#define IDC_EDIT_HD_FILE_NAME 1140 /* add hard disk dialog */ #define IDC_EDIT_HD_FILE_NAME 1160 /* add hard disk dialog */
#define IDC_EDIT_HD_SPT 1141 #define IDC_EDIT_HD_SPT 1161
#define IDC_EDIT_HD_HPC 1142 #define IDC_EDIT_HD_HPC 1162
#define IDC_EDIT_HD_CYL 1143 #define IDC_EDIT_HD_CYL 1163
#define IDC_EDIT_HD_SIZE 1144 #define IDC_EDIT_HD_SIZE 1164
#define IDC_COMBO_HD_TYPE 1145 #define IDC_COMBO_HD_TYPE 1165
#define IDC_PBAR_IMG_CREATE 1146 #define IDC_PBAR_IMG_CREATE 1166
#define IDC_REMOV_DEVICES 1150 /* removable dev config */ #define IDC_REMOV_DEVICES 1170 /* removable dev config */
#define IDC_LIST_FLOPPY_DRIVES 1151 #define IDC_LIST_FLOPPY_DRIVES 1171
#define IDC_COMBO_FD_TYPE 1152 #define IDC_COMBO_FD_TYPE 1172
#define IDC_CHECKTURBO 1153 #define IDC_CHECKTURBO 1173
#define IDC_CHECKBPB 1154 #define IDC_CHECKBPB 1174
#define IDC_LIST_CDROM_DRIVES 1155 #define IDC_LIST_CDROM_DRIVES 1175
#define IDC_COMBO_CD_BUS 1156 #define IDC_COMBO_CD_BUS 1176
#define IDC_COMBO_CD_ID 1157 #define IDC_COMBO_CD_ID 1177
#define IDC_COMBO_CD_LUN 1158 #define IDC_COMBO_CD_LUN 1178
#define IDC_COMBO_CD_CHANNEL_IDE 1159 #define IDC_COMBO_CD_CHANNEL_IDE 1179
#define IDC_LIST_ZIP_DRIVES 1160 #define IDC_LIST_ZIP_DRIVES 1180
#define IDC_COMBO_ZIP_BUS 1161 #define IDC_COMBO_ZIP_BUS 1181
#define IDC_COMBO_ZIP_ID 1162 #define IDC_COMBO_ZIP_ID 1182
#define IDC_COMBO_ZIP_LUN 1163 #define IDC_COMBO_ZIP_LUN 1183
#define IDC_COMBO_ZIP_CHANNEL_IDE 1164 #define IDC_COMBO_ZIP_CHANNEL_IDE 1184
#define IDC_CHECK250 1165 #define IDC_CHECK250 1185
#define IDC_COMBO_CD_SPEED 1166 #define IDC_COMBO_CD_SPEED 1186
#define IDC_SLIDER_GAIN 1180 /* sound gain dialog */ #define IDC_SLIDER_GAIN 1190 /* sound gain dialog */
#define IDC_EDIT_FILE_NAME 1190 /* new floppy image dialog */ #define IDC_EDIT_FILE_NAME 1200 /* new floppy image dialog */
#define IDC_COMBO_DISK_SIZE 1191 #define IDC_COMBO_DISK_SIZE 1201
#define IDC_COMBO_RPM_MODE 1192 #define IDC_COMBO_RPM_MODE 1202
/* For the DeviceConfig code, re-do later. */ /* For the DeviceConfig code, re-do later. */
#define IDC_CONFIG_BASE 1200 #define IDC_CONFIG_BASE 1300
#define IDC_CONFIGURE_VID 1200 #define IDC_CONFIGURE_VID 1300
#define IDC_CONFIGURE_SND 1201 #define IDC_CONFIGURE_SND 1301
#define IDC_CONFIGURE_VOODOO 1202 #define IDC_CONFIGURE_VOODOO 1302
#define IDC_CONFIGURE_MOD 1203 #define IDC_CONFIGURE_MOD 1303
#define IDC_CONFIGURE_NET_TYPE 1204 #define IDC_CONFIGURE_NET_TYPE 1304
#define IDC_CONFIGURE_BUSLOGIC 1205 #define IDC_CONFIGURE_BUSLOGIC 1305
#define IDC_CONFIGURE_PCAP 1206 #define IDC_CONFIGURE_PCAP 1306
#define IDC_CONFIGURE_NET 1207 #define IDC_CONFIGURE_NET 1307
#define IDC_CONFIGURE_MIDI 1208 #define IDC_CONFIGURE_MIDI 1308
#define IDC_JOY1 1210 #define IDC_JOY1 1310
#define IDC_JOY2 1211 #define IDC_JOY2 1311
#define IDC_JOY3 1212 #define IDC_JOY3 1312
#define IDC_JOY4 1213 #define IDC_JOY4 1313
#define IDC_HDTYPE 1280 #define IDC_HDTYPE 1380
#define IDC_RENDER 1281 #define IDC_RENDER 1381
#define IDC_STATUS 1282 #define IDC_STATUS 1382
#define IDM_ABOUT 40001 #define IDM_ABOUT 40001

View File

@@ -36,6 +36,8 @@
#include "../nvr.h" #include "../nvr.h"
#include "../machine/machine.h" #include "../machine/machine.h"
#include "../game/gameport.h" #include "../game/gameport.h"
#include "../isamem.h"
#include "../isartc.h"
#include "../lpt.h" #include "../lpt.h"
#include "../mouse.h" #include "../mouse.h"
#include "../scsi/scsi.h" #include "../scsi/scsi.h"
@@ -103,6 +105,8 @@ static int temp_scsi_card, temp_ide_ter, temp_ide_qua;
static char temp_hdc_name[32]; static char temp_hdc_name[32];
static char *hdc_names[32]; static char *hdc_names[32];
static int temp_bugger; static int temp_bugger;
static int temp_isartc;
static int temp_isamem[ISAMEM_MAX];
static uint8_t temp_deviceconfig; static uint8_t temp_deviceconfig;
@@ -243,7 +247,12 @@ win_settings_init(void)
temp_ide_ter = ide_ter_enabled; temp_ide_ter = ide_ter_enabled;
temp_ide_qua = ide_qua_enabled; temp_ide_qua = ide_qua_enabled;
temp_bugger = bugger_enabled; temp_bugger = bugger_enabled;
temp_isartc = isartc_type;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
temp_isamem[i] = isamem_type[i];
mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0; mfm_tracking = xta_tracking = esdi_tracking = ide_tracking = 0;
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
scsi_tracking[i] = 0; scsi_tracking[i] = 0;
@@ -261,8 +270,8 @@ win_settings_init(void)
ide_tracking |= (1 << (hdd[i].ide_channel << 3)); ide_tracking |= (1 << (hdd[i].ide_channel << 3));
else if (hdd[i].bus == HDD_BUS_SCSI) else if (hdd[i].bus == HDD_BUS_SCSI)
scsi_tracking[hdd[i].scsi_id >> 3] |= (1 << ((hdd[i].scsi_id & 0x07) << 3)); scsi_tracking[hdd[i].scsi_id >> 3] |= (1 << ((hdd[i].scsi_id & 0x07) << 3));
} }
/* Floppy drives category */ /* Floppy drives category */
for (i = 0; i < FDD_NUM; i++) { for (i = 0; i < FDD_NUM; i++) {
temp_fdd_types[i] = fdd_get_type(i); temp_fdd_types[i] = fdd_get_type(i);
@@ -345,7 +354,12 @@ win_settings_changed(void)
i = i || (temp_ide_ter != ide_ter_enabled); i = i || (temp_ide_ter != ide_ter_enabled);
i = i || (temp_ide_qua != ide_qua_enabled); i = i || (temp_ide_qua != ide_qua_enabled);
i = i || (temp_bugger != bugger_enabled); i = i || (temp_bugger != bugger_enabled);
i = i || (temp_isartc != isartc_type);
/* ISA memory boards. */
for (j = 0; j < ISAMEM_MAX; j++)
i = i || (temp_isamem[j] != isamem_type[j]);
/* Hard disks category */ /* Hard disks category */
i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); i = i || memcmp(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
@@ -451,6 +465,10 @@ win_settings_save(void)
ide_qua_enabled = temp_ide_qua; ide_qua_enabled = temp_ide_qua;
bugger_enabled = temp_bugger; bugger_enabled = temp_bugger;
/* ISA memory boards. */
for (i = 0; i < ISAMEM_MAX; i++)
isamem_type[i] = temp_isamem[i];
/* Hard disks category */ /* Hard disks category */
memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t)); memcpy(hdd, temp_hdd, HDD_NUM * sizeof(hard_disk_t));
@@ -1077,7 +1095,7 @@ mpu401_present(void)
n = sound_card_get_internal_name(temp_sound_card); n = sound_card_get_internal_name(temp_sound_card);
if (n != NULL) { if (n != NULL) {
if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32") || !strcmp(n, "replysb16"))
return 1; return 1;
} }
@@ -1093,7 +1111,7 @@ mpu401_standalone_allow(void)
n = sound_card_get_internal_name(temp_sound_card); n = sound_card_get_internal_name(temp_sound_card);
md = midi_device_get_internal_name(temp_midi_device); md = midi_device_get_internal_name(temp_midi_device);
if (n != NULL) { if (n != NULL) {
if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32") || !strcmp(n, "replysb16"))
return 0; return 0;
} }
@@ -1275,8 +1293,22 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
break; break;
case IDC_CONFIGURE_MPU401: case IDC_CONFIGURE_MPU401:
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&mpu401_device); {
break; char *n;
n = sound_card_get_internal_name(sound_card_current);
if (n != NULL)
{
if (!strcmp(n, "ncraudio"))
mca_version = 1;
else
mca_version = 0;
}
temp_deviceconfig |= deviceconfig_open(hdlg, mca_version ? (void *)&mpu401_mca_device : (void *)&mpu401_device);
}
break;
} }
return FALSE; return FALSE;
@@ -1457,7 +1489,7 @@ static BOOL CALLBACK
win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
HWND h; HWND h;
int c, d, temp_hdc_type; int c, d, e, temp_hdc_type;
LPTSTR lptsTemp; LPTSTR lptsTemp;
const device_t *scsi_dev; const device_t *scsi_dev;
@@ -1526,6 +1558,65 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa
h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); h=GetDlgItem(hdlg, IDC_CHECK_BUGGER);
SendMessage(h, BM_SETCHECK, temp_bugger, 0); SendMessage(h, BM_SETCHECK, temp_bugger, 0);
/* Populate the ISA RTC card dropdown. */
e = 0;
h = GetDlgItem(hdlg, IDC_COMBO_ISARTC);
for (d = 0; ; d++) {
char *s = isartc_get_name(d);
if (!s[0])
break;
settings_device_to_list[d] = e;
if (d == 0) {
/* Translate "None". */
SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112));
} else {
mbstowcs(lptsTemp, s, strlen(s) + 1);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
}
settings_list_to_device[e] = d;
e++;
}
SendMessage(h, CB_SETCURSEL, temp_isartc, 0);
h = GetDlgItem(hdlg, IDC_CONFIGURE_ISARTC);
if (temp_isartc != 0)
EnableWindow(h, TRUE);
else
EnableWindow(h, FALSE);
/* Populate the ISA memory card dropdowns. */
for (c = 0; c < ISAMEM_MAX; c++) {
e = 0;
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_1 + c);
for (d = 0; ; d++) {
char *s = isamem_get_name(d);
if (!s[0])
break;
settings_device_to_list[d] = e;
if (d == 0) {
/* Translate "None". */
SendMessage(h, CB_ADDSTRING, 0, win_get_string(IDS_2112));
} else {
mbstowcs(lptsTemp, s, strlen(s) + 1);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
}
settings_list_to_device[e] = d;
e++;
}
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);
}
free(lptsTemp); free(lptsTemp);
return TRUE; return TRUE;
@@ -1565,6 +1656,96 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa
EnableWindow(h, FALSE); EnableWindow(h, FALSE);
break; break;
case IDC_CONFIGURE_ISARTC:
h = GetDlgItem(hdlg, IDC_COMBO_ISARTC);
temp_isartc = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)isartc_get_device(temp_isartc));
break;
case IDC_COMBO_ISARTC:
h = GetDlgItem(hdlg, IDC_COMBO_ISARTC);
temp_isartc = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
h = GetDlgItem(hdlg, IDC_CONFIGURE_ISARTC);
if (temp_isartc != 0)
EnableWindow(h, TRUE);
else
EnableWindow(h, FALSE);
break;
case IDC_CONFIGURE_ISAMEM_1:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_1);
temp_isamem[0] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)isamem_get_device(temp_isamem[0]));
break;
case IDC_CONFIGURE_ISAMEM_2:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_2);
temp_isamem[1] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)isamem_get_device(temp_isamem[1]));
break;
case IDC_CONFIGURE_ISAMEM_3:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_3);
temp_isamem[2] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)isamem_get_device(temp_isamem[2]));
break;
case IDC_CONFIGURE_ISAMEM_4:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_4);
temp_isamem[3] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)isamem_get_device(temp_isamem[3]));
break;
case IDC_COMBO_ISAMEM_1:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_1);
temp_isamem[0] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
h = GetDlgItem(hdlg, IDC_CONFIGURE_ISAMEM_1);
if (temp_isamem[0] != 0)
EnableWindow(h, TRUE);
else
EnableWindow(h, FALSE);
break;
case IDC_COMBO_ISAMEM_2:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_2);
temp_isamem[1] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
h = GetDlgItem(hdlg, IDC_CONFIGURE_ISAMEM_2);
if (temp_isamem[1] != 0)
EnableWindow(h, TRUE);
else
EnableWindow(h, FALSE);
break;
case IDC_COMBO_ISAMEM_3:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_3);
temp_isamem[2] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
h = GetDlgItem(hdlg, IDC_CONFIGURE_ISAMEM_3);
if (temp_isamem[2] != 0)
EnableWindow(h, TRUE);
else
EnableWindow(h, FALSE);
break;
case IDC_COMBO_ISAMEM_4:
h = GetDlgItem(hdlg, IDC_COMBO_ISAMEM_4);
temp_isamem[3] = settings_list_to_device[SendMessage(h, CB_GETCURSEL, 0, 0)];
h = GetDlgItem(hdlg, IDC_CONFIGURE_ISAMEM_4);
if (temp_isamem[3] != 0)
EnableWindow(h, TRUE);
else
EnableWindow(h, FALSE);
break;
case IDC_CHECK_IDE_TER: case IDC_CHECK_IDE_TER:
h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER); h = GetDlgItem(hdlg, IDC_CHECK_IDE_TER);
temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0); temp_ide_ter = SendMessage(h, BM_GETCHECK, 0, 0);