Skip to content

Commit

Permalink
Matrox Mystique: Fix display flickering issues for real
Browse files Browse the repository at this point in the history
Direct3D tests under Windows 95 do not flicker anymore, and the MSICUBE sample program renders correctly.
  • Loading branch information
Cacodemon345 committed Dec 23, 2023
1 parent 539f9a0 commit 7bba9ce
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions src/video/vid_mga.c
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,28 @@ mystique_out(uint16_t addr, uint8_t val, void *priv)
if (mystique->crtcext_idx < 6)
mystique->crtcext_regs[mystique->crtcext_idx] = val;

if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE))
{
svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4);
if (mystique->type >= MGA_1064SG)
svga->rowoffset <<= 1;
svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd];
if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) {
svga->rowoffset <<= 1;
svga->ma_latch <<= 1;
}
if (mystique->type >= MGA_1064SG) {
svga->ma_latch <<= 1;
if (svga->ma_latch != mystique->ma_latch_old) {
if (svga->interlace && svga->oddeven)
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1);
else
svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2);
mystique->ma_latch_old = svga->ma_latch;
}
}
}

if (mystique->crtcext_idx == 4) {
if (svga->gdcreg[6] & 0xc) {
/*64k banks*/
Expand Down Expand Up @@ -886,6 +908,7 @@ mystique_recalctimings(svga_t *svga)
if (mystique->type >= MGA_1064SG) {
/*Mystique, unlike most SVGA cards, allows display start to take
effect mid-screen*/
svga->ma_latch <<= 1;
#ifdef CHANGE_MA
if (svga->ma_latch != mystique->ma_latch_old) {
if (svga->interlace && svga->oddeven)
Expand Down Expand Up @@ -2767,7 +2790,7 @@ run_dma(mystique_t *mystique)
case DMA_STATE_SEC:
switch (mystique->dma.secaddress & DMA_MODE_MASK) {
case DMA_MODE_REG:
if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) {
mystique->endprdmasts_pending = 1;
mystique->dma.state = DMA_STATE_IDLE;
Expand All @@ -2786,7 +2809,7 @@ run_dma(mystique_t *mystique)
words_transferred++;
}

if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) {
mystique->endprdmasts_pending = 1;
mystique->dma.state = DMA_STATE_IDLE;
Expand Down Expand Up @@ -2820,7 +2843,7 @@ run_dma(mystique_t *mystique)
mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3;

words_transferred++;
if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) {
mystique->endprdmasts_pending = 1;
mystique->dma.state = DMA_STATE_IDLE;
Expand All @@ -2837,7 +2860,7 @@ run_dma(mystique_t *mystique)
case DMA_MODE_BLIT:
{
uint32_t val;
if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) {
mystique->endprdmasts_pending = 1;
mystique->dma.state = DMA_STATE_IDLE;
Expand All @@ -2857,7 +2880,7 @@ run_dma(mystique_t *mystique)
blit_iload_write(mystique, val, 32);

words_transferred++;
if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) {
if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) {
mystique->endprdmasts_pending = 1;
mystique->dma.state = DMA_STATE_IDLE;
Expand Down

0 comments on commit 7bba9ce

Please sign in to comment.