Skip to content

Commit

Permalink
MGA: Count for cases where DMA header data is not immediately available
Browse files Browse the repository at this point in the history
Fixes crashes on NT 4.0
  • Loading branch information
Cacodemon345 committed Dec 19, 2023
1 parent 111b623 commit efe9784
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions src/video/vid_mga.c
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
* Copyright 2008-2020 Sarah Walker.
*/
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
@@ -512,6 +513,8 @@ typedef struct mystique_t {
pri_header, sec_header,
iload_header;

bool words_expected, sec_words_expected;

mutex_t *lock;
} dma;

@@ -2664,13 +2667,21 @@ run_dma(mystique_t *mystique)
case DMA_STATE_PRI:
switch (mystique->dma.primaddress & DMA_MODE_MASK) {
case DMA_MODE_REG:
if (mystique->dma.pri_state == 0) {
if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) {
dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4);
mystique->dma.primaddress += 4;
words_transferred++;
}

if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) {
if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK) && !mystique->dma.words_expected)
{
/* Wait until more data is available. */
mystique->dma.words_expected = 1;
break;
}

mystique->dma.words_expected = 0;
if ((mystique->dma.pri_header & 0xff) != 0x15) {
uint32_t val;
uint32_t reg_addr;

@@ -2709,7 +2720,7 @@ run_dma(mystique_t *mystique)
case DMA_STATE_SEC:
switch (mystique->dma.secaddress & DMA_MODE_MASK) {
case DMA_MODE_REG:
if (mystique->dma.sec_state == 0) {
if (mystique->dma.sec_state == 0 && !mystique->dma.sec_words_expected) {
dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4);
mystique->dma.secaddress += 4;
words_transferred++;
@@ -2718,6 +2729,14 @@ run_dma(mystique_t *mystique)
uint32_t val;
uint32_t reg_addr;

if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK) && !mystique->dma.sec_words_expected)
{
/* Wait until more data is available. */
mystique->dma.sec_words_expected = 1;
break;
}

mystique->dma.sec_words_expected = 0;
dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4);
mystique->dma.secaddress += 4;

0 comments on commit efe9784

Please sign in to comment.