Merge pull request #782 from nerd73/master

Add the AMI Excalibur, a VLB OPTi 596/597 machine.
This commit is contained in:
OBattler
2020-06-05 19:20:45 +02:00
committed by GitHub
12 changed files with 174 additions and 15 deletions

125
src/chipset/opti5x7.c Normal file
View File

@@ -0,0 +1,125 @@
/*Based off the OPTI 82C546/82C547 datasheet.
The earlier 596/597 appears to be register compatible with the 546/547 from testing.*/
#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/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/mem.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
typedef struct
{
uint8_t cur_reg,
regs[64];
port_92_t *port_92;
} opti5x7_t;
static void
opti5x7_recalcmapping(opti5x7_t *dev)
{
uint32_t shflags = 0;
shadowbios = 0;
shadowbios_write = 0;
shadowbios |= !!(dev->regs[0x06] & 0x05);
shadowbios_write |= !!(dev->regs[0x06] & 0x0a);
shflags = (dev->regs[0x06] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->regs[0x06] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state(0xe0000, 0x10000, shflags);
shflags = (dev->regs[0x06] & 0x04) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
shflags |= (dev->regs[0x06] & 0x08) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state(0xf0000, 0x10000, shflags);
flushmmucache();
}
static void
opti5x7_write(uint16_t addr, uint8_t val, void *priv)
{
opti5x7_t *dev = (opti5x7_t *) priv;
// pclog("Write %02x to OPTi 5x7 address %02x\n", val, addr);
switch (addr) {
case 0x22:
dev->cur_reg = val;
break;
case 0x24:
dev->regs[dev->cur_reg] = val;
if (dev->cur_reg == 0x02) {
cpu_cache_ext_enabled = val & 0x10;
}
if (dev->cur_reg == 0x06) {
opti5x7_recalcmapping(dev);
}
break;
}
}
static uint8_t
opti5x7_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
opti5x7_t *dev = (opti5x7_t *) priv;
switch (addr) {
case 0x24:
// pclog("Read from OPTI 5x7 register %02x\n", dev->cur_reg);
ret = dev->regs[dev->cur_reg];
break;
}
return ret;
}
static void
opti5x7_close(void *priv)
{
opti5x7_t *dev = (opti5x7_t *) priv;
free(dev);
}
static void *
opti5x7_init(const device_t *info)
{
opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t));
memset(dev, 0, sizeof(opti5x7_t));
io_sethandler(0x0022, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti5x7_read, NULL, NULL, opti5x7_write, NULL, NULL, dev);
dev->port_92 = device_add(&port_92_device);
// pclog("OPTi 5x7 init\n");
opti5x7_recalcmapping(dev);
return dev;
}
const device_t opti5x7_device = {
"OPTi 82C5x6/82C5x7",
0,
0,
opti5x7_init, opti5x7_close, NULL,
NULL, NULL, NULL,
NULL
};

View File

@@ -141,7 +141,7 @@ CPU *cpu_s;
int cpu_effective; int cpu_effective;
int cpu_multi; int cpu_multi;
double cpu_dmulti; double cpu_dmulti;
int cpu_16bitbus; int cpu_16bitbus, cpu_64bitbus;
int cpu_busspeed; int cpu_busspeed;
int cpu_cyrix_alignment; int cpu_cyrix_alignment;
int CPUID; int CPUID;
@@ -309,7 +309,7 @@ cpu_set(void)
isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP); isdx4 = (cpu_s->cpu_type >= CPU_iDX4) && (cpu_s->cpu_type < CPU_WINCHIP);
is_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) || is_am486 = (cpu_s->cpu_type == CPU_Am486SX) || (cpu_s->cpu_type == CPU_Am486SX2) || (cpu_s->cpu_type == CPU_Am486DX) ||
(cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86); (cpu_s->cpu_type == CPU_Am486DX2) || (cpu_s->cpu_type == CPU_Am486DX4) || (cpu_s->cpu_type == CPU_Am5x86);
is_pentium = (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX); is_pentium = (cpu_s->cpu_type == CPU_P24T) || (cpu_s->cpu_type == CPU_PENTIUM) || (cpu_s->cpu_type == CPU_PENTIUMMMX);
/* Not Pentiums, but they share the same SMM save state table layout. */ /* Not Pentiums, but they share the same SMM save state table layout. */
is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4); is_pentium |= (cpu_s->cpu_type == CPU_i486DX2) || (cpu_s->cpu_type == CPU_iDX4);
/* The WinChip datasheet claims these are Pentium-compatible. */ /* The WinChip datasheet claims these are Pentium-compatible. */
@@ -335,7 +335,8 @@ cpu_set(void)
#endif #endif
cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC ); cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC );
cpu_64bitbus = (cpu_s->cpu_type >= CPU_WINCHIP);
if (cpu_s->multi) if (cpu_s->multi)
cpu_busspeed = cpu_s->rspeed / cpu_s->multi; cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
else else
@@ -995,6 +996,7 @@ cpu_set(void)
#endif #endif
break; break;
case CPU_P24T:
case CPU_PENTIUM: case CPU_PENTIUM:
#ifdef USE_DYNAREC #ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
@@ -1787,7 +1789,8 @@ cpu_CPUID(void)
break; break;
} }
break; break;
case CPU_P24T:
case CPU_PENTIUM: case CPU_PENTIUM:
if (!EAX) if (!EAX)
{ {
@@ -2697,6 +2700,7 @@ void cpu_RDMSR()
} }
break; break;
case CPU_P24T:
case CPU_PENTIUM: case CPU_PENTIUM:
case CPU_PENTIUMMMX: case CPU_PENTIUMMMX:
EAX = EDX = 0; EAX = EDX = 0;
@@ -3175,7 +3179,8 @@ void cpu_WRMSR()
break; break;
} }
break; break;
case CPU_P24T:
case CPU_PENTIUM: case CPU_PENTIUM:
case CPU_PENTIUMMMX: case CPU_PENTIUMMMX:
switch (ECX) switch (ECX)

View File

@@ -52,6 +52,7 @@ enum {
CPU_Cx486DX4, CPU_Cx486DX4,
CPU_Am5x86, CPU_Am5x86,
CPU_Cx5x86, CPU_Cx5x86,
CPU_P24T,
CPU_WINCHIP, /* 586 class CPUs */ CPU_WINCHIP, /* 586 class CPUs */
CPU_WINCHIP2, CPU_WINCHIP2,
CPU_PENTIUM, CPU_PENTIUM,
@@ -370,7 +371,7 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128)
/* Global variables. */ /* Global variables. */
extern int cpu_iscyrix; extern int cpu_iscyrix;
extern int cpu_16bitbus; extern int cpu_16bitbus, cpu_64bitbus;
extern int cpu_busspeed, cpu_pci_speed; extern int cpu_busspeed, cpu_pci_speed;
extern int cpu_multi; extern int cpu_multi;
extern double cpu_dmulti; extern double cpu_dmulti;
@@ -379,8 +380,8 @@ extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4; extern int is8086, is286, is386, is486, is486sx, is486dx, is486sx2, is486dx2, isdx4;
extern int is_am486, is_pentium, is_k5, is_k6, is_p6; extern int is_am486, is_pentium, is_k5, is_k6, is_p6;
extern int hascache; extern int hascache;
extern int isibm486; extern int isibm486;
extern int is_rapidcad; extern int is_rapidcad;
extern int hasfpu; extern int hasfpu;
#define CPU_FEATURE_RDTSC (1 << 0) #define CPU_FEATURE_RDTSC (1 << 0)

View File

@@ -288,8 +288,8 @@ CPU cpus_i486[] = {
{"iDX4/100", CPU_iDX4, 100000000, 3.0, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"iDX4/100", CPU_iDX4, 100000000, 3.0, 0x483, 0x483, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
{"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9}, {"iDX4 OverDrive 75", CPU_iDX4, 75000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
{"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12}, {"iDX4 OverDrive 100", CPU_iDX4, 100000000, 3.0, 0x1480, 0x1480, 0x0000, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 12},
{"Pentium OverDrive 63", CPU_PENTIUM, 62500000, 2.5, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, {"Pentium OverDrive 63", CPU_P24T, 62500000, 2.5, 0x1531, 0x1531, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
{"Pentium OverDrive 83", CPU_PENTIUM, 83333333, 2.5, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10}, {"Pentium OverDrive 83", CPU_P24T, 83333333, 2.5, 0x1532, 0x1532, 0x0000, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
{"", -1, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0} {"", -1, 0, 0, 0, 0, 0x0000, 0, 0, 0, 0, 0, 0}
}; };

View File

@@ -48,6 +48,7 @@ extern const device_t i440zx_device;
/* OPTi */ /* OPTi */
extern const device_t opti495_device; extern const device_t opti495_device;
extern const device_t opti5x7_device;
/* C&T */ /* C&T */
extern const device_t neat_device; extern const device_t neat_device;

View File

@@ -253,6 +253,8 @@ extern const device_t *at_cpqiii_get_device(void);
#endif #endif
/* m_at_socket4_5.c */ /* m_at_socket4_5.c */
extern int machine_at_excalibur_init(const machine_t *);
extern int machine_at_batman_init(const machine_t *); extern int machine_at_batman_init(const machine_t *);
extern int machine_at_ambradp60_init(const machine_t *); extern int machine_at_ambradp60_init(const machine_t *);
#if defined(DEV_BRANCH) && defined(USE_VPP60) #if defined(DEV_BRANCH) && defined(USE_VPP60)

View File

@@ -41,6 +41,26 @@
#include <86box/sio.h> #include <86box/sio.h>
#include <86box/video.h> #include <86box/video.h>
#include <86box/machine.h> #include <86box/machine.h>
int
machine_at_excalibur_init(const machine_t *model)
{
int ret;
ret = bios_load_linear_inverted(L"roms/machines/excalibur/S75P.ROM",
0x000e0000, 131072, 0);
if (bios_only || !ret)
return ret;
machine_at_common_init(model);
device_add(&ide_vlb_device);
device_add(&opti5x7_device);
device_add(&fdc37c663_device);
device_add(&keyboard_at_ami_device);
return ret;
}
static void static void

View File

@@ -206,6 +206,9 @@ const machine_t machines[] = {
{ "[486 PCI] Zida Tomato 4DP", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL }, { "[486 PCI] Zida Tomato 4DP", "4dps", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1, 255, 1, 127, machine_at_4dps_init, NULL },
/* Socket 4 machines */ /* Socket 4 machines */
/* OPTi 596/597 */
{ "[Socket 4 OPTi] AMI Excalibur VLB", "excalibur", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_VLB | MACHINE_AT | MACHINE_HDC, 1, 64, 1, 127, machine_at_excalibur_init, NULL },
/* 430LX */ /* 430LX */
{ "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL }, { "[Socket 4 LX] IBM Ambra DP60 PCI", "ambradp60", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_PCI | MACHINE_ISA | MACHINE_AT | MACHINE_PS2 | MACHINE_HDC, 2, 128, 2, 127, machine_at_ambradp60_init, NULL },
#if defined(DEV_BRANCH) && defined(USE_VPP60) #if defined(DEV_BRANCH) && defined(USE_VPP60)

View File

@@ -1029,8 +1029,10 @@ pit_set_clock(int clock)
TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32)); TIMER_USEC = (uint64_t)((cpuclock / 1000000.0) * (double)(1ull << 32));
isa_timing = (cpuclock / (double)8000000.0); isa_timing = (cpuclock / (double)8000000.0);
if (cpu_64bitbus)
bus_timing = (cpuclock / (double)cpu_busspeed); bus_timing = (cpuclock / ((double)cpu_busspeed) / 2);
else
bus_timing = (cpuclock / (double)cpu_busspeed);
pci_timing = (cpuclock / (double)cpu_pci_speed); pci_timing = (cpuclock / (double)cpu_pci_speed);
/* PCICLK in us for use with timer_on_auto(). */ /* PCICLK in us for use with timer_on_auto(). */

View File

@@ -1210,7 +1210,7 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *p)
case 0x09: return 0; /*Programming interface*/ case 0x09: return 0; /*Programming interface*/
case 0x0a: return 0x00; /*Supports VGA interface, XGA compatible*/ case 0x0a: return 0x00; /*Supports VGA interface, XGA compatible*/
case 0x0b: return is_pentium ? 0x03 : 0x00; /* This has to be done in order to make this card work with the two 486 PCI machines. */ case 0x0b: return cpu_64bitbus ? 0x03 : 0x00; /* This has to be done in order to make this card work with the two 486 PCI machines. */
case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x10: return 0x00; /*Linear frame buffer address*/
case 0x11: return 0x00; case 0x11: return 0x00;

View File

@@ -515,7 +515,7 @@ CPUOBJ := cpu.o cpu_table.o \
$(DYNARECOBJ) $(DYNARECOBJ)
CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \
intel_4x0.o neat.o opti495.o scamp.o scat.o \ intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \
sis_85c471.o sis_85c496.o \ sis_85c471.o sis_85c496.o \
via_apollo.o via_vpx.o wd76c10.o via_apollo.o via_vpx.o wd76c10.o

View File

@@ -519,7 +519,7 @@ CPUOBJ := cpu.o cpu_table.o \
$(DYNARECOBJ) $(DYNARECOBJ)
CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \ CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \
intel_4x0.o neat.o opti495.o scamp.o scat.o \ intel_4x0.o neat.o opti495.o opti5x7.o scamp.o scat.o \
sis_85c471.o sis_85c496.o \ sis_85c471.o sis_85c496.o \
via_apollo.o via_vpx.o wd76c10.o via_apollo.o via_vpx.o wd76c10.o