Assorted changes and bugfixes and added the two IMS 8848 machines.

This commit is contained in:
OBattler
2021-10-09 17:37:09 +02:00
parent 79999818f5
commit 1c2d1e702b
20 changed files with 1086 additions and 150 deletions

View File

@@ -724,6 +724,26 @@ pc_init_modules(void)
wchar_t temp[512];
char tempc[512];
c = m = 0;
while (machine_get_internal_name_ex(c) != NULL) {
m = machine_available(c);
if (!m)
pclog("Missing machine: %s\n", machine_getname_ex(c));
c++;
}
c = m = 0;
while (video_get_internal_name(c) != NULL) {
memset(tempc, 0, sizeof(tempc));
device_get_name(video_card_getdevice(c), 0, tempc);
if ((c > 1) && !(tempc[0]))
break;
m = video_card_available(c);
if (!m)
pclog("Missing video card: %s\n", tempc);
c++;
}
pc_log("Scanning for ROM images:\n");
c = m = 0;
while (machine_get_internal_name_ex(m) != NULL) {

411
src/chipset/ims8848.c Normal file
View File

@@ -0,0 +1,411 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the IMS 8848/8849 chipset.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Tiseno100,
*
* Copyright 2021 Miran Grca.
* Copyright 2021 Tiseno100.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pci.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
/*
IMS 884x Configuration Registers
Note: IMS 884x are rebadged ATMEL AT 40411/40412 chipsets
By: Tiseno100, Miran Grca(OBattler)
Register 00h:
Bit 3: F0000-FFFFF Shadow Enable
Bit 2: E0000-EFFFF Shadow Enable
Bit 0: ????
Register 04h:
Bit 3: Cache Write Hit Wait State
Bit 2: Cache Read Hit Wait State
Register 06h:
Bit 3: System BIOS Cacheable (1: Yes / 0: No)
Bit 1: Power Management Mode (1: IRQ / 0: SMI#)
Register 08h:
Bit 2: System BIOS Shadow Write (1: Enable / 0: Disable)
Bit 1: System BIOS Shadow Read?
Register 0Dh:
Bit 0: IO 100H-3FFH Idle Detect (1: Enable / 0: Disable)
Register 0Eh:
Bit 7: DMA & Local Bus Idle Detect (1: Enable / 0: Disable)
Bit 6: Floppy Disk Idle Detect (1: Enable / 0: Disable)
Bit 5: IDE Idle Detect (1: Enable / 0: Disable)
Bit 4: Serial Port Idle Detect (1: Enable / 0: Disable)
Bit 3: Parallel Port Idle Detect (1: Enable / 0: Disable)
Bit 2: Keyboard Idle Detect (1: Enable / 0: Disable)
Bit 1: Video Idle Detect (1: Enable / 0: Disable)
Register 12h:
Bits 3-2: Power Saving Timer (00 = 1 MIN, 01 = 3 MIN, 10 = 5 MIN, 11 = 8 MIN)
Bit 1: Base Memory (1: 512KB / 0: 640KB)
Register 1Ah:
Bit 3: Cache Write Hit W/S For PCI (1: Enabled / 0: Disable)
Bit 2: Cache Read Hit W/S For PCI (1: Enabled / 0: Disable)
Bit 1: VESA Clock Skew (1: 4ns/6ns, 0: No Delay/2ns)
Register 1Bh:
Bit 6: Enable SMRAM (always at 30000-4FFFF) in SMM
Bit 5: ????
Bit 4: Software SMI#
Bit 3: DC000-DFFFF Shadow Enable
Bit 2: D8000-DBFFF Shadow Enable
Bit 1: D4000-D7FFF Shadow Enable
Bit 0: D0000-D3FFF Shadow Enable
Register 1Ch:
Bits 7-4: INTA IRQ routing (0 = disabled, 1 to F = IRQ)
Bit 3: CC000-CFFFF Shadow Enable
Bit 2: C8000-CBFFF Shadow Enable
Bit 1: C4000-C7FFF Shadow Enable
Bit 0: C0000-C3FFF Shadow Enable
Register 1Dh:
Bits 7-4: INTB IRQ routing (0 = disabled, 1 to F = IRQ)
Register 1Eh:
Bits 7-4: INTC IRQ routing (0 = disabled, 1 to F = IRQ)
Bit 1: C4000-C7FFF Cacheable
Bit 0: C0000-C3FFF Cacheable
Register 21h:
Bits 7-4: INTD IRQ routing (0 = disabled, 1 to F = IRQ)
Register 22h:
Bit 5: Local Bus Master #2 select (0 = VESA, 1 = PCI)
Bit 4: Local Bus Master #1 select (0 = VESA, 1 = PCI)
Bits 1-0: Internal HADS# Delay Always (00 = No Delay, 01 = 1 Clk, 10 = 2 Clks)
Register 23h:
Bit 7: Seven Bits Tag (1: Enabled / 0: Disable)
Bit 3: Extend LBRDY#(VL Master) (1: Enabled / 0: Disable)
Bit 2: Sync LRDY#(VL Slave) (1: Enabled / 0: Disable)
Bit 0: HADS# Delay After LB. Cycle (1: Enabled / 0: Disable)
*/
typedef struct
{
uint8_t idx, access_data,
regs[256], pci_conf[256];
smram_t *smram;
} ims8848_t;
#ifdef ENABLE_IMS8848_LOG
int ims8848_do_log = ENABLE_IMS8848_LOG;
static void
ims8848_log(const char *fmt, ...)
{
va_list ap;
if (ims8848_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define ims8848_log(fmt, ...)
#endif
/* Shadow write always enabled, 1B and 1C control C000-DFFF read. */
static void
ims8848_recalc(ims8848_t *dev)
{
int i, state_on;
uint32_t base;
ims8848_log("SHADOW: 00 = %02X, 08 = %02X, 1B = %02X, 1C = %02X\n",
dev->regs[0x00], dev->regs[0x08], dev->regs[0x1b], dev->regs[0x1c]);
state_on = MEM_READ_INTERNAL;
state_on |= (dev->regs[0x08] & 0x04) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
for (i = 0; i < 2; i++) {
base = 0xe0000 + (i << 16);
if (dev->regs[0x00] & (1 << (i + 2)))
mem_set_mem_state_both(base, 0x10000, state_on);
else
mem_set_mem_state_both(base, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
}
for (i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
if (dev->regs[0x1c] & (1 << i))
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
else
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
base = 0xd0000 + (i << 14);
if (dev->regs[0x1b] & (1 << i))
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
else
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
}
flushmmucache_nopc();
}
static void
ims8848_base_memory(ims8848_t *dev)
{
/* We can use the proper mem_set_access to handle that. */
mem_set_mem_state_both(0x80000, 0x20000, (dev->regs[0x12] & 2) ?
(MEM_READ_DISABLED | MEM_WRITE_DISABLED) : (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL));
}
static void
ims8848_smram(ims8848_t *dev)
{
smram_disable_all();
smram_enable(dev->smram, 0x00030000, 0x00030000, 0x20000, dev->regs[0x1b] & 0x40, 1);
}
static void
ims8848_write(uint16_t addr, uint8_t val, void *priv)
{
ims8848_t *dev = (ims8848_t *) priv;
uint8_t old = dev->regs[dev->idx];
switch (addr) {
case 0x22:
ims8848_log("[W] IDX = %02X\n", val);
dev->idx = val;
break;
case 0x23:
ims8848_log("[W] IDX IN = %02X\n", val);
if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
dev->access_data = 1;
break;
case 0x24:
ims8848_log("[W] [%i] REG %02X = %02X\n", dev->access_data, dev->idx, val);
if (dev->access_data) {
dev->regs[dev->idx] = val;
switch (dev->idx) {
case 0x00: case 0x08: case 0x1b: case 0x1c:
/* Shadow RAM */
ims8848_recalc(dev);
if (dev->idx == 0x1b) {
ims8848_smram(dev);
if (!(old & 0x10) && (val & 0x10))
smi_line = 1;
} else if (dev->idx == 0x1c)
pci_set_irq_routing(PCI_INTA, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
break;
case 0x1d: case 0x1e:
pci_set_irq_routing(PCI_INTB + (dev->idx - 0x1d), (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
break;
case 0x21:
pci_set_irq_routing(PCI_INTD, (val >> 4) ? (val >> 4) : PCI_IRQ_DISABLED);
break;
case 0x12:
/* Base Memory */
ims8848_base_memory(dev);
break;
}
dev->access_data = 0;
}
break;
}
}
static uint8_t
ims8848_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
ims8848_t *dev = (ims8848_t *) priv;
#ifdef ENABLE_IMS8848_LOG
uint8_t old_ad = dev->access_data;
#endif
switch (addr) {
case 0x22:
ims8848_log("[R] IDX = %02X\n", ret);
ret = dev->idx;
break;
case 0x23:
ims8848_log("[R] IDX IN = %02X\n", ret);
ret = (dev->idx >> 4) | (dev->idx << 4);
break;
case 0x24:
if (dev->access_data) {
ret = dev->regs[dev->idx];
dev->access_data = 0;
}
ims8848_log("[R] [%i] REG %02X = %02X\n", old_ad, dev->idx, ret);
break;
}
return ret;
}
static void
ims8849_pci_write(int func, int addr, uint8_t val, void *priv)
{
ims8848_t *dev = (ims8848_t *)priv;
ims8848_log("IMS 884x-PCI: dev->regs[%02x] = %02x POST: %02x\n", addr, val, inb(0x80));
if (func == 0) switch (addr) {
case 0x04:
dev->pci_conf[addr] = val;
break;
case 0x05:
dev->pci_conf[addr] = val & 3;
break;
case 0x07:
dev->pci_conf[addr] &= val & 0xf7;
break;
case 0x0c ... 0x0d:
dev->pci_conf[addr] = val;
break;
case 0x52 ... 0x55:
dev->pci_conf[addr] = val;
break;
}
}
static uint8_t
ims8849_pci_read(int func, int addr, void *priv)
{
ims8848_t *dev = (ims8848_t *)priv;
uint8_t ret = 0xff;
if (func == 0)
ret = dev->pci_conf[addr];
return ret;
}
static void
ims8848_reset(void *priv)
{
ims8848_t *dev = (ims8848_t *)priv;
memset(dev->regs, 0x00, sizeof(dev->regs));
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
dev->pci_conf[0x00] = 0xe0; /* Integrated Micro Solutions (IMS) */
dev->pci_conf[0x01] = 0x10;
dev->pci_conf[0x02] = 0x49; /* 8849 */
dev->pci_conf[0x03] = 0x88;
dev->pci_conf[0x04] = 0x07;
dev->pci_conf[0x07] = 0x02;
dev->pci_conf[0x0b] = 0x06;
ims8848_recalc(dev); /* Shadow RAM Setup */
ims8848_base_memory(dev); /* Base Memory Setup */
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
ims8848_smram(dev);
}
static void
ims8848_close(void *priv)
{
ims8848_t *dev = (ims8848_t *) priv;
smram_del(dev->smram);
free(dev);
}
static void *
ims8848_init(const device_t *info)
{
ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t));
memset(dev, 0, sizeof(ims8848_t));
device_add(&port_92_device);
/* IMS 8848:
22h Index
23h Data Unlock
24h Data
IMS 8849:
PCI Device 0: IMS 8849 Dummy for compatibility reasons
*/
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
dev->smram = smram_add();
smram_set_separate_smram(1);
cpu_cache_ext_enabled = 1;
cpu_update_waitstates();
ims8848_reset(dev);
return dev;
}
const device_t ims8848_device = {
"IMS 8848/8849",
0,
0,
ims8848_init, ims8848_close, ims8848_reset,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -55,6 +55,7 @@ typedef struct
smram_locked, max_drb,
drb_unit, drb_default;
uint8_t regs[256], regs_locked[256];
uint8_t mem_state[256];
int type;
smram_t *smram_low, *smram_high;
} i4x0_t;
@@ -81,23 +82,18 @@ i4x0_log(const char *fmt, ...)
static void
i4x0_map(uint32_t addr, uint32_t size, int state)
i4x0_map(i4x0_t *dev, uint32_t addr, uint32_t size, int state)
{
switch (state & 3) {
case 0:
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
break;
case 1:
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY);
break;
case 2:
mem_set_mem_state_both(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
break;
case 3:
mem_set_mem_state_both(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
break;
uint32_t base = addr >> 12;
int states[4] = { MEM_READ_EXTANY | MEM_WRITE_EXTANY, MEM_READ_INTERNAL | MEM_WRITE_EXTANY,
MEM_READ_EXTANY | MEM_WRITE_INTERNAL, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL };
state &= 3;
if (dev->mem_state[base] != state) {
mem_set_mem_state_both(addr, size, states[state]);
dev->mem_state[base] = state;
flushmmucache_nopc();
}
flushmmucache_nopc();
}
@@ -584,10 +580,10 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
case 0x59: /* PAM0 */
if (dev->type <= INTEL_430NX) {
if ((regs[0x59] ^ val) & 0x0f)
i4x0_map(0x80000, 0x20000, val & 0x0f);
i4x0_map(dev, 0x80000, 0x20000, val & 0x0f);
}
if ((regs[0x59] ^ val) & 0xf0) {
i4x0_map(0xf0000, 0x10000, val >> 4);
i4x0_map(dev, 0xf0000, 0x10000, val >> 4);
shadowbios = (val & 0x10);
}
if (dev->type > INTEL_430NX)
@@ -597,44 +593,44 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x5a: /* PAM1 */
if ((regs[0x5a] ^ val) & 0x0f)
i4x0_map(0xc0000, 0x04000, val & 0xf);
i4x0_map(dev, 0xc0000, 0x04000, val & 0xf);
if ((regs[0x5a] ^ val) & 0xf0)
i4x0_map(0xc4000, 0x04000, val >> 4);
i4x0_map(dev, 0xc4000, 0x04000, val >> 4);
regs[0x5a] = val & 0x77;
break;
case 0x5b: /*PAM2 */
if ((regs[0x5b] ^ val) & 0x0f)
i4x0_map(0xc8000, 0x04000, val & 0xf);
i4x0_map(dev, 0xc8000, 0x04000, val & 0xf);
if ((regs[0x5b] ^ val) & 0xf0)
i4x0_map(0xcc000, 0x04000, val >> 4);
i4x0_map(dev, 0xcc000, 0x04000, val >> 4);
regs[0x5b] = val & 0x77;
break;
case 0x5c: /*PAM3 */
if ((regs[0x5c] ^ val) & 0x0f)
i4x0_map(0xd0000, 0x04000, val & 0xf);
i4x0_map(dev, 0xd0000, 0x04000, val & 0xf);
if ((regs[0x5c] ^ val) & 0xf0)
i4x0_map(0xd4000, 0x04000, val >> 4);
i4x0_map(dev, 0xd4000, 0x04000, val >> 4);
regs[0x5c] = val & 0x77;
break;
case 0x5d: /* PAM4 */
if ((regs[0x5d] ^ val) & 0x0f)
i4x0_map(0xd8000, 0x04000, val & 0xf);
i4x0_map(dev, 0xd8000, 0x04000, val & 0xf);
if ((regs[0x5d] ^ val) & 0xf0)
i4x0_map(0xdc000, 0x04000, val >> 4);
i4x0_map(dev, 0xdc000, 0x04000, val >> 4);
regs[0x5d] = val & 0x77;
break;
case 0x5e: /* PAM5 */
if ((regs[0x5e] ^ val) & 0x0f)
i4x0_map(0xe0000, 0x04000, val & 0xf);
i4x0_map(dev, 0xe0000, 0x04000, val & 0xf);
if ((regs[0x5e] ^ val) & 0xf0)
i4x0_map(0xe4000, 0x04000, val >> 4);
i4x0_map(dev, 0xe4000, 0x04000, val >> 4);
regs[0x5e] = val & 0x77;
break;
case 0x5f: /* PAM6 */
if ((regs[0x5f] ^ val) & 0x0f)
i4x0_map(0xe8000, 0x04000, val & 0xf);
i4x0_map(dev, 0xe8000, 0x04000, val & 0xf);
if ((regs[0x5f] ^ val) & 0xf0)
i4x0_map(0xec000, 0x04000, val >> 4);
i4x0_map(dev, 0xec000, 0x04000, val >> 4);
regs[0x5f] = val & 0x77;
break;
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64:

264
src/chipset/opti499.c Normal file
View File

@@ -0,0 +1,264 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the OPTi 82C493/82C499 chipset.
*
*
*
* Authors: Tiseno100,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2020 Tiseno100.
* Copyright 2016-2020 Miran Grca.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t idx,
regs[256], scratch[2];
} opti499_t;
#ifdef ENABLE_OPTI499_LOG
int opti499_do_log = ENABLE_OPTI499_LOG;
static void
opti499_log(const char *fmt, ...)
{
va_list ap;
if (opti499_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define opti499_log(fmt, ...)
#endif
static void
opti499_recalc(opti499_t *dev)
{
uint32_t base;
uint32_t i, shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
if (dev->regs[0x22] & 0x80) {
shadowbios = 1;
shadowbios_write = 0;
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
} else {
shadowbios = 0;
shadowbios_write = 1;
shflags = MEM_READ_INTERNAL | MEM_WRITE_DISABLED;
}
mem_set_mem_state_both(0xf0000, 0x10000, shflags);
for (i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if ((dev->regs[0x22] & ((base >= 0xe0000) ? 0x20 : 0x40)) &&
(dev->regs[0x23] & (1 << i))) {
shflags = MEM_READ_INTERNAL;
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
else
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
}
mem_set_mem_state_both(base, 0x4000, shflags);
}
for (i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
if ((dev->regs[0x26] & 0x10) && (dev->regs[0x26] & (1 << i))) {
shflags = MEM_READ_INTERNAL;
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x26] & 0x40) {
if (dev->regs[0x2d] && (1 << (i >> 1)))
shflags = MEM_READ_EXTANY;
else
shflags = MEM_READ_EXTERNAL;
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x2d] && (1 << (i >> 1)))
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
else
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
}
}
mem_set_mem_state_both(base, 0x4000, shflags);
}
flushmmucache_nopc();
}
static void
opti499_write(uint16_t addr, uint8_t val, void *priv)
{
opti499_t *dev = (opti499_t *) priv;
switch (addr) {
case 0x22:
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
dev->idx = val;
break;
case 0x24:
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
if (dev->idx == 0x20)
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
else
dev->regs[dev->idx] = val;
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
switch(dev->idx) {
case 0x20:
reset_on_hlt = !(val & 0x02);
break;
case 0x21:
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
cpu_update_waitstates();
break;
case 0x22: case 0x23:
case 0x26: case 0x2d:
opti499_recalc(dev);
break;
}
}
break;
case 0xe1: case 0xe2:
dev->scratch[addr] = val;
break;
}
}
static uint8_t
opti499_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
opti499_t *dev = (opti499_t *) priv;
switch (addr) {
case 0x22:
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
break;
case 0x24:
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
if (dev->idx == 0x2d)
ret = dev->regs[dev->idx] & 0xbf;
else
ret = dev->regs[dev->idx];
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
}
break;
case 0xe1:
case 0xe2:
ret = dev->scratch[addr];
break;
}
return ret;
}
static void
opti499_reset(void *priv)
{
opti499_t *dev = (opti499_t *) priv;
memset(dev->regs, 0xff, sizeof(dev->regs));
memset(&(dev->regs[0x20]), 0x00, 14 * sizeof(uint8_t));
dev->scratch[0] = dev->scratch[1] = 0xff;
dev->regs[0x22] = 0x84;
dev->regs[0x24] = 0x87;
dev->regs[0x25] = 0xf0;
dev->regs[0x27] = 0xd1;
dev->regs[0x28] = dev->regs[0x2a] = 0x80;
dev->regs[0x29] = dev->regs[0x2b] = 0x10;
dev->regs[0x2d] = 0x40;
reset_on_hlt = 1;
cpu_cache_ext_enabled = 0;
cpu_update_waitstates();
opti499_recalc(dev);
free(dev);
}
static void
opti499_close(void *priv)
{
opti499_t *dev = (opti499_t *) priv;
free(dev);
}
static void *
opti499_init(const device_t *info)
{
opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t));
memset(dev, 0, sizeof(opti499_t));
device_add(&port_92_device);
io_sethandler(0x0022, 0x0001, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev);
opti499_reset(dev);
io_sethandler(0x00e1, 0x0002, opti499_read, NULL, NULL, opti499_write, NULL, NULL, dev);
return dev;
}
const device_t opti499_device = {
"OPTi 82C499",
0,
1,
opti499_init, opti499_close, opti499_reset,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -79,40 +79,56 @@ typedef struct sis_5511_t
} sis_5511_t;
static void
sis_5511_shadow_recalc(int cur_reg, sis_5511_t *dev)
sis_5511_shadow_recalc(sis_5511_t *dev)
{
if (cur_reg == 0x86)
mem_set_mem_state_both(0xf0000, 0x10000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
else
{
mem_set_mem_state_both(0xc0000 + ((cur_reg & 7) << 15), 0x4000, ((dev->pci_conf[cur_reg] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
mem_set_mem_state_both(0xc4000 + ((cur_reg & 7) << 15), 0x4000, ((dev->pci_conf[cur_reg] & 8) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->pci_conf[cur_reg] & 2) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY));
}
int i, state;
uint32_t base;
flushmmucache_nopc();
for (i = 0x80; i <= 0x86; i++) {
if (i == 0x86) {
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(0xf0000, 0x10000, state);
pclog("000F0000-000FFFFF\n");
} else {
base = ((i & 0x07) << 15) + 0xc0000;
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(base, 0x4000, state);
pclog("%08X-%08X\n", base, base + 0x3fff);
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff);
}
}
flushmmucache_nopc();
}
static void
sis_5511_smram_recalc(sis_5511_t *dev)
{
smram_disable_all();
smram_disable_all();
switch (dev->pci_conf[0x65] >> 6)
{
case 0:
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
case 1:
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
case 2:
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
}
switch (dev->pci_conf[0x65] >> 6) {
case 0:
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
case 1:
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
case 2:
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
break;
}
flushmmucache();
}
void sis_5513_ide_handler(sis_5511_t *dev)
{
ide_pri_disable();
@@ -140,31 +156,19 @@ void sis_5513_bm_handler(sis_5511_t *dev)
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8);
}
static void
sis_5511_write(int func, int addr, uint8_t val, void *priv)
{
sis_5511_t *dev = (sis_5511_t *)priv;
sis_5511_t *dev = (sis_5511_t *)priv;
switch (addr)
{
case 0x04: /* Command - low byte */
dev->pci_conf[addr] = val;
break;
case 0x05: /* Command - high byte */
dev->pci_conf[addr] = val;
break;
case 0x06: /* Status - Low Byte */
dev->pci_conf[addr] &= val;
break;
case 0x07: /* Status - High Byte */
dev->pci_conf[addr] &= 0x16;
switch (addr) {
case 0x07: /* Status - High Byte */
dev->pci_conf[addr] &= 0xb0;
break;
case 0x50:
dev->pci_conf[addr] = (val & 0xf9) | 4;
dev->pci_conf[addr] = val;
cpu_cache_ext_enabled = !!(val & 0x40);
cpu_update_waitstates();
break;
@@ -177,8 +181,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val & 0x3f;
break;
case 0x53:
case 0x54:
case 0x53: case 0x54:
dev->pci_conf[addr] = val;
break;
@@ -186,15 +189,17 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val & 0xf8;
break;
case 0x57:
case 0x58:
case 0x59:
case 0x56 ... 0x59:
dev->pci_conf[addr] = val;
break;
case 0x5a:
/* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC.
The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h.
The latter (bit 6) means the chipset intercepts all odd FXh to 64h.
Bit 5 sets fast reset latency. This should be fixed on the other SiS
chipsets as well. */
dev->pci_conf[addr] = val;
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
break;
case 0x5b:
@@ -214,22 +219,18 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x5f:
dev->pci_conf[addr] = val;
dev->pci_conf[addr] = val & 0xfe;
break;
case 0x60:
dev->pci_conf[addr] = val & 0x3e;
if (!!(val & 2) && (dev->pci_conf[0x68] & 1))
{
if ((dev->pci_conf[0x68] & 1) && (val & 2)) {
smi_line = 1;
dev->pci_conf[0x69] |= 1;
}
break;
case 0x61: /* STPCLK# Assertion Timer */
case 0x62: /* STPCLK# De-assertion Timer */
case 0x63: /* System Standby Timer */
case 0x64:
case 0x61 ... 0x64:
dev->pci_conf[addr] = val;
break;
@@ -242,8 +243,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] = val & 0x7f;
break;
case 0x67:
case 0x68:
case 0x67: case 0x68:
dev->pci_conf[addr] = val;
break;
@@ -251,11 +251,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
dev->pci_conf[addr] &= val;
break;
case 0x6a:
case 0x6b:
case 0x6c:
case 0x6d:
case 0x6e:
case 0x6a ... 0x6e:
dev->pci_conf[addr] = val;
break;
@@ -329,8 +325,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv)
case 0x85:
case 0x86:
dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee);
sis_5511_shadow_recalc(addr, dev);
sis_5511_smram_recalc(dev);
sis_5511_shadow_recalc(dev);
break;
case 0x90: /* 5512 General Purpose Register Index */
@@ -620,24 +615,45 @@ sis_5513_isa_read(uint16_t addr, void *priv)
return 0xff;
}
static void
sis_5511_reset(void *priv)
{
sis_5511_t *dev = (sis_5511_t *)priv;
sis_5511_t *dev = (sis_5511_t *)priv;
/* SiS 5511 */
dev->pci_conf[0x00] = 0x39;
dev->pci_conf[0x01] = 0x10;
dev->pci_conf[0x02] = 0x11;
dev->pci_conf[0x03] = 0x55;
dev->pci_conf[0x04] = 0x07;
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
dev->pci_conf[0x07] = 0x02;
dev->pci_conf[0x08] = 0x00;
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
dev->pci_conf[0x0b] = 0x06;
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
dev->pci_conf[0x52] = 0x20;
dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00;
dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00;
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00;
dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00;
dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00;
dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff;
dev->pci_conf[0x63] = 0xff;
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
dev->pci_conf[0x66] = 0x00;
dev->pci_conf[0x67] = 0xff;
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00;
dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00;
cpu_cache_ext_enabled = 0;
cpu_update_waitstates();
/* SiS 5511 */
dev->pci_conf[0x00] = 0x39;
dev->pci_conf[0x01] = 0x10;
dev->pci_conf[0x02] = 0x11;
dev->pci_conf[0x03] = 0x55;
dev->pci_conf[0x04] = 7;
dev->pci_conf[0x07] = 2;
dev->pci_conf[0x0b] = 6;
dev->pci_conf[0x52] = 0x20;
dev->pci_conf[0x61] = 0xff;
dev->pci_conf[0x62] = 0xff;
dev->pci_conf[0x63] = 0xff;
dev->pci_conf[0x67] = 0xff;
dev->pci_conf[0x6b] = 0xff;
dev->pci_conf[0x6c] = 0xff;
dev->pci_conf[0x70] = 4;
@@ -652,6 +668,15 @@ sis_5511_reset(void *priv)
dev->pci_conf[0x7c] = 4;
dev->pci_conf[0x7e] = 4;
dev->pci_conf[0x7f] = 0x80;
dev->pci_conf[0x80] = 0x00;
dev->pci_conf[0x81] = 0x00;
dev->pci_conf[0x82] = 0x00;
dev->pci_conf[0x83] = 0x00;
dev->pci_conf[0x84] = 0x00;
dev->pci_conf[0x85] = 0x00;
dev->pci_conf[0x86] = 0x00;
sis_5511_smram_recalc(dev);
sis_5511_shadow_recalc(dev);
/* SiS 5513 */
dev->pci_conf_sb[0][0x00] = 0x39;

View File

@@ -124,6 +124,10 @@ int isa_cycles, cpu_inited,
timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate, timing_misaligned;
uint32_t cpu_features, cpu_fast_off_flags;
uint32_t _tr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t cache_index = 0;
uint8_t _cache[2048];
uint64_t cpu_CR4_mask, tsc = 0;
uint64_t pmc[2] = {0, 0};
@@ -2290,6 +2294,7 @@ amd_k_invalid_rdmsr:
EDX = tsc >> 32;
break;
}
pclog("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
break;
case CPU_PENTIUMPRO:
@@ -2695,6 +2700,7 @@ amd_k_invalid_wrmsr:
case CPU_CxGX1:
case CPU_Cx6x86MX:
#endif
pclog("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
switch (ECX) {
case 0x10:
tsc = EAX | ((uint64_t)EDX << 32);

View File

@@ -542,6 +542,9 @@ extern uint64_t amd_efer, star;
#define msw cpu_state.CR0.w
extern uint32_t cr2, cr3, cr4;
extern uint32_t dr[8];
extern uint32_t _tr[8];
extern uint32_t cache_index;
extern uint8_t _cache[2048];
/*Segments -

View File

@@ -282,13 +282,13 @@ reset_common(int hard)
if (is386 || hard)
EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0;
/* if (hard) {
if (hard) {
makeznptable();
resetreadlookup();
makemod1table();
cpu_set_edx();
mmu_perm = 4;
} */
}
x86seg_reset();
#ifdef USE_DYNAREC
if (hard)
@@ -308,15 +308,19 @@ reset_common(int hard)
if (hard) {
if (is486)
smbase = is_am486dxl ? 0x00060000 : 0x00030000;
// ppi_reset();
ppi_reset();
}
in_sys = 0;
shadowbios = shadowbios_write = 0;
alt_access = cpu_end_block_after_ins = 0;
if (hard)
if (hard) {
reset_on_hlt = hlt_reset_pending = 0;
cache_index = 0;
memset(_tr, 0x00, sizeof(_tr));
memset(_cache, 0x00, sizeof(_cache));
}
if (!is286)
reset_808x(hard);
@@ -328,15 +332,6 @@ void
resetx86(void)
{
reset_common(1);
/* ---- */
makeznptable();
resetreadlookup();
makemod1table();
cpu_set_edx();
mmu_perm = 4;
ppi_reset();
/* ---- */
soft_reset_mask = 0;
}

View File

@@ -607,6 +607,8 @@ static int opF7_l_a32(uint32_t fetchdat)
static int opHLT(uint32_t fetchdat)
{
pclog("HLT: CS = %04X, DS = %04X, ES = %04X, SS = %04X, IP = %04X\n", CS, DS, ES, SS, cpu_state.pc);
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
{
x86gpf(NULL,0);

View File

@@ -256,54 +256,113 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat)
return 0;
}
static void opMOV_r_TRx(void)
{
uint32_t base;
base = _tr[4] & 0xfffff800;
switch (cpu_reg) {
case 3:
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
cache_index = (cache_index + 4) & 0xf;
break;
}
cpu_state.regs[cpu_rm].l = _tr[cpu_reg];
CLOCK_CYCLES(6);
}
static int opMOV_r_TRx_a16(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
{
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
cpu_state.regs[cpu_rm].l = 0;
CLOCK_CYCLES(6);
opMOV_r_TRx();
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
return 0;
}
static int opMOV_r_TRx_a32(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
{
x86gpf(NULL, 0);
return 1;
}
fetch_ea_32(fetchdat);
cpu_state.regs[cpu_rm].l = 0;
CLOCK_CYCLES(6);
opMOV_r_TRx();
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
return 0;
}
static void opMOV_TRx_r(void)
{
uint32_t base;
int i, ctl;
_tr[cpu_reg] = cpu_state.regs[cpu_rm].l;
base = _tr[4] & 0xfffff800;
ctl = _tr[5] & 3;
switch (cpu_reg) {
case 3:
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
*(uint32_t *) &(_cache[cache_index]) = _tr[3];
cache_index = (cache_index + 4) & 0xf;
break;
case 4:
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
break;
case 5:
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
if (!(_tr[5] & (1 << 19))) {
switch(ctl) {
case 0:
pclog(" Cache fill or read...\n", base);
break;
case 1:
base += (_tr[5] & 0x7f0);
pclog(" Writing 16 bytes to %08X...\n", base);
for (i = 0; i < 16; i += 4)
mem_writel_phys(base + i, *(uint32_t *) &(_cache[i]));
break;
case 2:
base += (_tr[5] & 0x7f0);
pclog(" Reading 16 bytes from %08X...\n", base);
for (i = 0; i < 16; i += 4)
*(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i);
break;
case 3:
pclog(" Cache invalidate/flush...\n", base);
break;
}
}
break;
}
CLOCK_CYCLES(6);
}
static int opMOV_TRx_r_a16(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
{
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
CLOCK_CYCLES(6);
opMOV_TRx_r();
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0);
return 0;
}
static int opMOV_TRx_r_a32(uint32_t fetchdat)
{
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)))
{
x86gpf(NULL, 0);
return 1;
}
fetch_ea_16(fetchdat);
CLOCK_CYCLES(6);
fetch_ea_32(fetchdat);
opMOV_TRx_r();
PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1);
return 0;
}

View File

@@ -39,11 +39,14 @@
typedef struct
{
uint8_t jumper;
uint8_t type, jumper;
} phoenix_486_jumper_t;
#ifdef ENABLE_PHOENIX_486_JUMPER_LOG
int phoenix_486_jumper_do_log = ENABLE_PHOENIX_486_JUMPER_LOG;
static void
phoenix_486_jumper_log(const char *fmt, ...)
{
@@ -59,14 +62,19 @@ phoenix_486_jumper_log(const char *fmt, ...)
#define phoenix_486_jumper_log(fmt, ...)
#endif
static void
phoenix_486_jumper_write(uint16_t addr, uint8_t val, void *priv)
{
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv;
phoenix_486_jumper_log("Phoenix 486 Jumper: Write %02x\n", val);
dev->jumper = val;
if (dev->type == 1)
dev->jumper = val & 0xbf;
else
dev->jumper = val;
}
static uint8_t
phoenix_486_jumper_read(uint16_t addr, void *priv)
{
@@ -76,6 +84,21 @@ phoenix_486_jumper_read(uint16_t addr, void *priv)
}
static void
phoenix_486_jumper_reset(void *priv)
{
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) priv;
if (dev->type == 1)
dev->jumper = 0x00;
else {
dev->jumper = 0x9f;
if (gfxcard != 0x01)
dev->jumper |= 0x40;
}
}
static void
phoenix_486_jumper_close(void *priv)
{
@@ -84,26 +107,38 @@ phoenix_486_jumper_close(void *priv)
free(dev);
}
static void *
phoenix_486_jumper_init(const device_t *info)
{
phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t));
memset(dev, 0, sizeof(phoenix_486_jumper_t));
dev->jumper = 0x9f;
if (gfxcard != 0x01)
dev->jumper |= 0x40;
dev->type = info->local;
phoenix_486_jumper_reset(dev);
io_sethandler(0x0078, 0x0001, phoenix_486_jumper_read, NULL, NULL, phoenix_486_jumper_write, NULL, NULL, dev);
return dev;
}
const device_t phoenix_486_jumper_device = {
"Phoenix 486 Jumper Readout",
0,
0,
phoenix_486_jumper_init, phoenix_486_jumper_close, NULL,
phoenix_486_jumper_init, phoenix_486_jumper_close, phoenix_486_jumper_reset,
{ NULL }, NULL, NULL,
NULL
};
const device_t phoenix_486_jumper_pci_device = {
"Phoenix 486 Jumper Readout (PCI machines)",
0,
1,
phoenix_486_jumper_init, phoenix_486_jumper_close, phoenix_486_jumper_reset,
{ NULL }, NULL, NULL,
NULL
};

View File

@@ -59,6 +59,9 @@ extern const device_t headland_ht18a_device;
extern const device_t headland_ht18b_device;
extern const device_t headland_ht18c_device;
/* IMS */
extern const device_t ims8848_device;
/* Intel */
extern const device_t intel_82335_device;
extern const device_t i420ex_device;
@@ -162,7 +165,7 @@ extern const device_t wd76c10_device;
/* Miscellaneous Hardware */
extern const device_t phoenix_486_jumper_device;
extern const device_t vpc2007_device;
extern const device_t phoenix_486_jumper_pci_device;
#if defined(DEV_BRANCH) && defined(USE_OLIVETTI)
extern const device_t olivetti_eva_device;

View File

@@ -366,6 +366,9 @@ extern int machine_at_ms4145_init(const machine_t *);
extern int machine_at_sbc_490_init(const machine_t *);
extern int machine_at_tf_486_init(const machine_t *);
extern int machine_at_pci400c_b_init(const machine_t *);
extern int machine_at_g486ip_init(const machine_t *);
extern int machine_at_itoxstar_init(const machine_t *);
extern int machine_at_arb1423c_init(const machine_t *);
extern int machine_at_arb1479_init(const machine_t *);

View File

@@ -89,6 +89,7 @@
/* Internal execute access, external read access. */
#define MEM_READ_EXTERNAL_EX 0
#define MEM_READ_SMRAM (ACCESS_X_SMRAM | ACCESS_R_SMRAM)
#define MEM_READ_CACHE (ACCESS_X_CACHE | ACCESS_R_CACHE)
#define MEM_READ_SMRAM_EX (ACCESS_X_SMRAM)
#define MEM_EXEC_SMRAM MEM_READ_SMRAM_EX
#define MEM_READ_SMRAM_2 (ACCESS_R_SMRAM)
@@ -104,6 +105,7 @@
#define MEM_WRITE_ROMCS (ACCESS_W_ROMCS)
#define MEM_WRITE_EXTANY (ACCESS_W_ROMCS)
#define MEM_WRITE_SMRAM (ACCESS_W_SMRAM)
#define MEM_WRITE_CACHE (ACCESS_W_CACHE)
/* Theese two are going to be identical. */
#define MEM_WRITE_DISABLED_EX MEM_READ_DISABLED
#define MEM_WRITE_MASK 0x03e0

View File

@@ -52,6 +52,8 @@ extern void smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, ui
extern int smram_enabled(smram_t *smr);
/* Changes the SMRAM state. */
extern void smram_state_change(smram_t *smr, int smm, int flags);
/* Enables or disables the use of a separate SMRAM for addresses below A0000. */
extern void smram_set_separate_smram(uint8_t set);
#endif /*EMU_SMRAM_H*/

View File

@@ -319,6 +319,9 @@ inb(uint16_t port)
if (port == 0x1ed)
ret = 0xfe;
if (port == 0x2b60)
ret = 0x00;
io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret);
return(ret);

View File

@@ -66,7 +66,7 @@ machine_at_acc386_init(const machine_t *model)
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
device_add(&fdc_at_device);
return ret;
}
@@ -1147,6 +1147,68 @@ machine_at_486sp3_init(const machine_t *model)
}
int
machine_at_pci400c_b_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/pci400c-b/032295.ROM",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&ide_isa_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 3, 2, 1); /* 0F = Slot 1 */
pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0E = Slot 2 */
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0D = Slot 3 */
pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 0C = Slot 4 */
device_add(&keyboard_ps2_ami_pci_device); /* Assume AMI Megakey 1993 stanalone ('P')
because of the Tekram machine below. */
device_add(&ims8848_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_g486ip_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/g486ip/G486IP.BIN",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&ide_isa_device);
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 1 */
pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */
pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 3 */
device_add(&keyboard_ps2_ami_pci_device); /* AMI Megakey 1993 stanalone ('P') */
device_add(&ims8848_device);
if (fdc_type == FDC_INTERNAL)
device_add(&fdc_at_device);
return ret;
}
int
machine_at_486sp3g_init(const machine_t *model)
{
@@ -1623,8 +1685,10 @@ machine_at_hot433_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886af_device);
device_add(&um8669f_device);
device_add(&intel_flash_bxt_device);
device_add(&keyboard_at_ami_device);
// device_add(&intel_flash_bxt_device);
device_add(&sst_flash_29ee010_device);
// device_add(&keyboard_at_ami_device);
device_add(&keyboard_ps2_ami_device);
return ret;
}
@@ -1652,6 +1716,7 @@ machine_at_atc1415_init(const machine_t *model)
device_add(&umc_hb4_device);
device_add(&umc_8886af_device);
device_add(&intel_flash_bxt_device);
device_add(&keyboard_at_ami_device);
if (fdc_type == FDC_INTERNAL)

View File

@@ -432,6 +432,10 @@ const machine_t machines[] = {
{ "[i420TX] ASUS PCI/I-486SP3", "486sp3", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL | MACHINE_SCSI, 1024, 131072, 1024, 127, machine_at_486sp3_init, NULL },
/* This has the Phoenix MultiKey KBC firmware. */
{ "[i420TX] Intel Classic/PCI", "alfredo", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_alfredo_init, NULL },
/* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */
{ "[IMS 8848] J-Bond PCI400C-B", "pci400c_b", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_pci400c_b_init, NULL },
/* This has a standalone AMI Megakey 1993, which is type 'P'. */
{ "[IMS 8848] Tekram G486IP", "g486ip", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_g486ip_init, NULL },
/* This has an AMIKey-2, which is an updated version of type 'H'. */
{ "[SiS 496] ASUS PVI-486SP3C", "486sp3c", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_486sp3c_init, NULL },
/* This has an AMIKey-2, which is an updated version of type 'H'. */

View File

@@ -32,6 +32,9 @@
static smram_t *base_smram, *last_smram;
static uint8_t use_separate_smram = 0;
static uint8_t smram[0x40000];
#ifdef ENABLE_SMRAM_LOG
int smram_do_log = ENABLE_SMRAM_LOG;
@@ -61,8 +64,10 @@ smram_read(uint32_t addr, void *priv)
if (new_addr >= (1 << 30))
return mem_read_ram_2gb(new_addr, priv);
else
else if (!use_separate_smram || (new_addr >= 0xa0000))
return mem_read_ram(new_addr, priv);
else
return dev->mapping.exec[addr - dev->host_base];
}
@@ -74,8 +79,10 @@ smram_readw(uint32_t addr, void *priv)
if (new_addr >= (1 << 30))
return mem_read_ram_2gbw(new_addr, priv);
else
else if (!use_separate_smram || (new_addr >= 0xa0000))
return mem_read_ramw(new_addr, priv);
else
return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]);
}
@@ -87,8 +94,10 @@ smram_readl(uint32_t addr, void *priv)
if (new_addr >= (1 << 30))
return mem_read_ram_2gbl(new_addr, priv);
else
else if (!use_separate_smram || (new_addr >= 0xa0000))
return mem_read_raml(new_addr, priv);
else
return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]);
}
@@ -98,7 +107,10 @@ smram_write(uint32_t addr, uint8_t val, void *priv)
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
mem_write_ram(new_addr, val, priv);
if (!use_separate_smram || (new_addr >= 0xa0000))
mem_write_ram(new_addr, val, priv);
else
dev->mapping.exec[addr - dev->host_base] = val;
}
@@ -108,7 +120,10 @@ smram_writew(uint32_t addr, uint16_t val, void *priv)
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
mem_write_ramw(new_addr, val, priv);
if (!use_separate_smram || (new_addr >= 0xa0000))
mem_write_ramw(new_addr, val, priv);
else
*(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
}
@@ -118,7 +133,10 @@ smram_writel(uint32_t addr, uint32_t val, void *priv)
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
mem_write_raml(new_addr, val, priv);
if (!use_separate_smram || (new_addr >= 0xa0000))
mem_write_raml(new_addr, val, priv);
else
*(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
}
@@ -263,6 +281,8 @@ smram_add(void)
smram_write,smram_writew,smram_writel,
ram, MEM_MAPPING_SMRAM, temp_smram);
smram_set_separate_smram(0);
return temp_smram;
}
@@ -326,10 +346,21 @@ smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
smr->size = size;
mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size);
if (smr->ram_base < (1 << 30))
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
else
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
if (!use_separate_smram || (smr->ram_base >= 0x000a0000)) {
if (smr->ram_base < (1 << 30))
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
else
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
} else {
if (smr->ram_base == 0x00030000)
mem_mapping_set_exec(&(smr->mapping), smram);
else if (smr->ram_base == 0x00040000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x10000);
else if (smr->ram_base == 0x00060000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x20000);
else if (smr->ram_base == 0x00070000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x30000);
}
smram_map(0, host_base, size, flags_normal);
smram_map(1, host_base, size, flags_smm);
@@ -364,3 +395,10 @@ smram_state_change(smram_t *smr, int smm, int flags)
smram_map(smm, smr->host_base, smr->size, flags);
}
void
smram_set_separate_smram(uint8_t set)
{
use_separate_smram = set;
}

View File

@@ -593,7 +593,7 @@ CHIPSETOBJ := 82c100.o acc2168.o \
cs4031.o cs8230.o \
ali1429.o ali1489.o ali1531.o ali1541.o ali1543.o ali1621.o ali6117.o \
gc100.o headland.o \
intel_82335.o intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \
ims8848.o intel_82335.o intel_420ex.o intel_4x0.o intel_sio.o intel_piix.o ioapic.o \
neat.o \
opti283.o opti291.o opti391.o opti495.o opti822.o opti895.o opti5x7.o \
scamp.o scat.o \