Skip to content

Commit

Permalink
Reimplement S3 ViRGE reset and move PCI TRC CPU reset to outside the …
Browse files Browse the repository at this point in the history
…recompiled block, fixes 86Box#2903.
  • Loading branch information
OBattler committed Jun 12, 2024
1 parent 1169ce6 commit a369bc2
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 98 deletions.
2 changes: 2 additions & 0 deletions src/cpu/386_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ uint32_t dr[8];
uint32_t use32;
int stack32;

int cpu_init = 0;

uint32_t *eal_r;
uint32_t *eal_w;

Expand Down
14 changes: 14 additions & 0 deletions src/cpu/386_dynarec.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ exec386_dynarec_int(void)
CPU_BLOCK_END();
}

if (cpu_init)
CPU_BLOCK_END();

if (cpu_state.abrt)
CPU_BLOCK_END();
if (smi_line)
Expand Down Expand Up @@ -592,6 +595,9 @@ exec386_dynarec_dyn(void)
# endif
CPU_BLOCK_END();

if (cpu_init)
CPU_BLOCK_END();

if ((cpu_state.flags & T_FLAG) || (trap == 2))
CPU_BLOCK_END();
if (smi_line)
Expand Down Expand Up @@ -689,6 +695,9 @@ exec386_dynarec_dyn(void)
# endif
CPU_BLOCK_END();

if (cpu_init)
CPU_BLOCK_END();

if (cpu_state.flags & T_FLAG)
CPU_BLOCK_END();
if (smi_line)
Expand Down Expand Up @@ -768,6 +777,11 @@ exec386_dynarec(int32_t cycs)
exec386_dynarec_dyn();
}

if (cpu_init) {
cpu_init = 0;
resetx86();
}

if (cpu_state.abrt) {
flags_rebuild();
tempi = cpu_state.abrt & ABRT_MASK;
Expand Down
4 changes: 3 additions & 1 deletion src/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include "x86.h"
#include "x87_sf.h"
#include <86box/device.h>
#include <86box/machine.h>
Expand Down Expand Up @@ -504,7 +505,8 @@ cpu_set(void)
acycs = 0;
#endif

soft_reset_pci = 0;
soft_reset_pci = 0;
cpu_init = 0;

cpu_alt_reset = 0;
unmask_a20_in_smm = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ extern int nmi_enable;
extern int oddeven;
extern int inttype;

extern int cpu_init;

extern uint32_t use32;
extern uint32_t rmdat;
extern uint32_t easeg;
Expand Down
8 changes: 8 additions & 0 deletions src/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <86box/86box.h>
#include <86box/machine.h>
#include "cpu.h"
#include "x86.h"
#include <86box/io.h>
#include <86box/pic.h>
#include <86box/mem.h>
Expand Down Expand Up @@ -420,7 +421,14 @@ pci_trc_reset(uint8_t val)
flushmmucache();
}

#ifdef USE_DYNAREC
if (cpu_use_dynarec)
cpu_init = 1;
else
resetx86();
#else
resetx86();
#endif
}

void
Expand Down
136 changes: 39 additions & 97 deletions src/video/vid_s3_virge.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ typedef struct virge_t {
int onboard;
} 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_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 };
Expand Down Expand Up @@ -4248,114 +4250,49 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
}

static void
s3_virge_reset(void *priv)
s3_virge_disable_handlers(virge_t *dev)
{
virge_t *virge = (virge_t *) priv;
svga_t *svga = &virge->svga;

memset(svga->crtc, 0x00, sizeof(svga->crtc));
svga->crtc[0] = 63;
svga->crtc[6] = 255;
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);
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;
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;
}

default:
virge->fifo_slots_num = 8;
virge->svga.crtc[0x6c] = 1;
virge->svga.crtc[0x59] = 0x70;
break;
}
static void
s3_virge_reset(void *priv)
{
virge_t *dev = (virge_t *) priv;

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;
if (reset_state != NULL) {
s3_virge_disable_handlers(dev);
reset_state->pci_slot = dev->pci_slot;

default:
break;
}
if (virge->local == S3_VIRGE_GX)
virge->svga.crtc[0x36] |= (1 << 2);
*dev = *reset_state;
}

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 *
s3_virge_init(const device_t *info)
{
const char *bios_fn;
virge_t *virge = malloc(sizeof(virge_t));

memset(virge, 0, sizeof(virge_t));
virge_t *virge = calloc(1, sizeof(virge_t));
reset_state = calloc(1, sizeof(virge_t));

virge->bilinear_enabled = device_get_config_int("bilinear");
virge->dithering_enabled = device_get_config_int("dithering");
Expand Down Expand Up @@ -4595,6 +4532,8 @@ s3_virge_init(const device_t *info)

virge->local = info->local;

*reset_state = *virge;

return virge;
}

Expand All @@ -4615,6 +4554,9 @@ s3_virge_close(void *priv)
ddc_close(virge->ddc);
i2c_gpio_close(virge->i2c);

free(reset_state);
reset_state = NULL;

free(virge);
}

Expand Down

0 comments on commit a369bc2

Please sign in to comment.