Reimplement S3 ViRGE reset and move PCI TRC CPU reset to outside the recompiled block, fixes #2903.

This commit is contained in:
OBattler
2024-06-12 20:46:27 +02:00
parent 1169ce68a5
commit a369bc2d05
6 changed files with 68 additions and 98 deletions

View File

@@ -51,6 +51,8 @@ uint32_t dr[8];
uint32_t use32; uint32_t use32;
int stack32; int stack32;
int cpu_init = 0;
uint32_t *eal_r; uint32_t *eal_r;
uint32_t *eal_w; uint32_t *eal_w;

View File

@@ -350,6 +350,9 @@ exec386_dynarec_int(void)
CPU_BLOCK_END(); CPU_BLOCK_END();
} }
if (cpu_init)
CPU_BLOCK_END();
if (cpu_state.abrt) if (cpu_state.abrt)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (smi_line) if (smi_line)
@@ -592,6 +595,9 @@ exec386_dynarec_dyn(void)
# endif # endif
CPU_BLOCK_END(); CPU_BLOCK_END();
if (cpu_init)
CPU_BLOCK_END();
if ((cpu_state.flags & T_FLAG) || (trap == 2)) if ((cpu_state.flags & T_FLAG) || (trap == 2))
CPU_BLOCK_END(); CPU_BLOCK_END();
if (smi_line) if (smi_line)
@@ -689,6 +695,9 @@ exec386_dynarec_dyn(void)
# endif # endif
CPU_BLOCK_END(); CPU_BLOCK_END();
if (cpu_init)
CPU_BLOCK_END();
if (cpu_state.flags & T_FLAG) if (cpu_state.flags & T_FLAG)
CPU_BLOCK_END(); CPU_BLOCK_END();
if (smi_line) if (smi_line)
@@ -768,6 +777,11 @@ exec386_dynarec(int32_t cycs)
exec386_dynarec_dyn(); exec386_dynarec_dyn();
} }
if (cpu_init) {
cpu_init = 0;
resetx86();
}
if (cpu_state.abrt) { if (cpu_state.abrt) {
flags_rebuild(); flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK; tempi = cpu_state.abrt & ABRT_MASK;

View File

@@ -29,6 +29,7 @@
#define HAVE_STDARG_H #define HAVE_STDARG_H
#include <86box/86box.h> #include <86box/86box.h>
#include "cpu.h" #include "cpu.h"
#include "x86.h"
#include "x87_sf.h" #include "x87_sf.h"
#include <86box/device.h> #include <86box/device.h>
#include <86box/machine.h> #include <86box/machine.h>
@@ -504,7 +505,8 @@ cpu_set(void)
acycs = 0; acycs = 0;
#endif #endif
soft_reset_pci = 0; soft_reset_pci = 0;
cpu_init = 0;
cpu_alt_reset = 0; cpu_alt_reset = 0;
unmask_a20_in_smm = 0; unmask_a20_in_smm = 0;

View File

@@ -59,6 +59,8 @@ extern int nmi_enable;
extern int oddeven; extern int oddeven;
extern int inttype; extern int inttype;
extern int cpu_init;
extern uint32_t use32; extern uint32_t use32;
extern uint32_t rmdat; extern uint32_t rmdat;
extern uint32_t easeg; extern uint32_t easeg;

View File

@@ -23,6 +23,7 @@
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/machine.h> #include <86box/machine.h>
#include "cpu.h" #include "cpu.h"
#include "x86.h"
#include <86box/io.h> #include <86box/io.h>
#include <86box/pic.h> #include <86box/pic.h>
#include <86box/mem.h> #include <86box/mem.h>
@@ -420,7 +421,14 @@ pci_trc_reset(uint8_t val)
flushmmucache(); flushmmucache();
} }
#ifdef USE_DYNAREC
if (cpu_use_dynarec)
cpu_init = 1;
else
resetx86();
#else
resetx86(); resetx86();
#endif
} }
void void

View File

@@ -299,6 +299,8 @@ typedef struct virge_t {
int onboard; int onboard;
} virge_t; } virge_t;
static virge_t *reset_state = NULL;
static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 };
static video_timings_t timing_diamond_stealth3d_3000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_diamond_stealth3d_3000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 };
static video_timings_t timing_virge_dx_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; static video_timings_t timing_virge_dx_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 };
@@ -4247,115 +4249,50 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
} }
} }
static void
s3_virge_disable_handlers(virge_t *dev)
{
io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL,
s3_virge_out, NULL, NULL, dev);
mem_mapping_disable(&dev->linear_mapping);
mem_mapping_disable(&dev->mmio_mapping);
mem_mapping_disable(&dev->new_mmio_mapping);
mem_mapping_disable(&dev->svga.mapping);
mem_mapping_disable(&dev->bios_rom.mapping);
/* Save all the mappings and the timers because they are part of linked lists. */
reset_state->linear_mapping = dev->linear_mapping;
reset_state->mmio_mapping = dev->mmio_mapping;
reset_state->new_mmio_mapping = dev->new_mmio_mapping;
reset_state->svga.mapping = dev->svga.mapping;
reset_state->bios_rom.mapping = dev->bios_rom.mapping;
reset_state->svga.timer = dev->svga.timer;
reset_state->svga.timer8514 = dev->svga.timer8514;
reset_state->tri_timer = dev->tri_timer;
}
static void static void
s3_virge_reset(void *priv) s3_virge_reset(void *priv)
{ {
virge_t *virge = (virge_t *) priv; virge_t *dev = (virge_t *) priv;
svga_t *svga = &virge->svga;
memset(svga->crtc, 0x00, sizeof(svga->crtc)); if (reset_state != NULL) {
svga->crtc[0] = 63; s3_virge_disable_handlers(dev);
svga->crtc[6] = 255; reset_state->pci_slot = dev->pci_slot;
svga->dispontime = 1000ULL << 32;
svga->dispofftime = 1000ULL << 32;
svga->bpp = 8;
io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); *dev = *reset_state;
io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge);
memset(virge->pci_regs, 0x00, 256);
virge->pci_regs[PCI_REG_COMMAND] = 3;
virge->pci_regs[0x05] = 0;
virge->pci_regs[0x06] = 0;
virge->pci_regs[0x07] = 2;
virge->pci_regs[0x32] = 0x0c;
virge->pci_regs[0x3d] = 1;
virge->pci_regs[0x3e] = 4;
virge->pci_regs[0x3f] = 0xff;
switch (virge->local) {
case S3_VIRGE_325:
case S3_DIAMOND_STEALTH3D_2000:
virge->fifo_slots_num = 8;
virge->svga.crtc[0x59] = 0x70;
break;
case S3_DIAMOND_STEALTH3D_3000:
case S3_STB_VELOCITY_3D:
virge->fifo_slots_num = 8;
virge->svga.crtc[0x59] = 0x70;
break;
case S3_VIRGE_GX2:
case S3_DIAMOND_STEALTH3D_4000:
virge->fifo_slots_num = 16;
virge->svga.crtc[0x6c] = 1;
virge->svga.crtc[0x59] = 0x70;
break;
case S3_TRIO_3D2X:
virge->fifo_slots_num = 16;
virge->svga.crtc[0x6c] = 1;
virge->svga.crtc[0x59] = 0x70;
break;
default:
virge->fifo_slots_num = 8;
virge->svga.crtc[0x6c] = 1;
virge->svga.crtc[0x59] = 0x70;
break;
} }
if (virge->chip == S3_VIRGEGX2)
virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (1 << 5);
else {
switch (virge->memory_size) {
case 2:
if (virge->chip == S3_VIRGEVX) {
virge->svga.crtc[0x36] = (0 << 5);
} else
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5);
break;
case 8:
if (virge->chip == S3_TRIO3D2X)
virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5);
else
virge->svga.crtc[0x36] = (3 << 5);
break;
case 4:
if (virge->chip == S3_VIRGEVX)
virge->svga.crtc[0x36] = (1 << 5);
else if (virge->chip == S3_TRIO3D2X)
virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (2 << 5);
else
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
break;
default:
break;
}
if (virge->local == S3_VIRGE_GX)
virge->svga.crtc[0x36] |= (1 << 2);
}
virge->svga.crtc[0x37] = 1 | (7 << 5);
virge->svga.crtc[0x53] = 8;
if (!virge->onboard)
mem_mapping_disable(&virge->bios_rom.mapping);
s3_virge_updatemapping(virge);
mem_mapping_disable(&virge->mmio_mapping);
mem_mapping_disable(&virge->new_mmio_mapping);
} }
static void * static void *
s3_virge_init(const device_t *info) s3_virge_init(const device_t *info)
{ {
const char *bios_fn; const char *bios_fn;
virge_t *virge = malloc(sizeof(virge_t)); virge_t *virge = calloc(1, sizeof(virge_t));
reset_state = calloc(1, sizeof(virge_t));
memset(virge, 0, sizeof(virge_t));
virge->bilinear_enabled = device_get_config_int("bilinear"); virge->bilinear_enabled = device_get_config_int("bilinear");
virge->dithering_enabled = device_get_config_int("dithering"); virge->dithering_enabled = device_get_config_int("dithering");
@@ -4595,6 +4532,8 @@ s3_virge_init(const device_t *info)
virge->local = info->local; virge->local = info->local;
*reset_state = *virge;
return virge; return virge;
} }
@@ -4615,6 +4554,9 @@ s3_virge_close(void *priv)
ddc_close(virge->ddc); ddc_close(virge->ddc);
i2c_gpio_close(virge->i2c); i2c_gpio_close(virge->i2c);
free(reset_state);
reset_state = NULL;
free(virge); free(virge);
} }