MGA: 3D busmastering now works (albeit slowly)

This commit is contained in:
Cacodemon345
2023-12-20 16:19:29 +06:00
parent bf30678d5f
commit 7a8fe414c5

View File

@@ -2672,6 +2672,11 @@ run_dma(mystique_t *mystique)
thread_wait_mutex(mystique->dma.lock); thread_wait_mutex(mystique->dma.lock);
if (mystique->dma.state == DMA_STATE_IDLE) { if (mystique->dma.state == DMA_STATE_IDLE) {
if (!(mystique->status & STATUS_ENDPRDMASTS))
{
/* Force this to appear. */
mystique->endprdmasts_pending = 1;
}
thread_release_mutex(mystique->dma.lock); thread_release_mutex(mystique->dma.lock);
return; return;
} }
@@ -2872,13 +2877,13 @@ fifo_thread(void *priv)
mystique_t *mystique = (mystique_t *) priv; mystique_t *mystique = (mystique_t *) priv;
while (mystique->thread_run) { while (mystique->thread_run) {
int words_transferred = 0;
thread_set_event(mystique->fifo_not_full_event); thread_set_event(mystique->fifo_not_full_event);
thread_wait_event(mystique->wake_fifo_thread, -1); thread_wait_event(mystique->wake_fifo_thread, -1);
thread_reset_event(mystique->wake_fifo_thread); thread_reset_event(mystique->wake_fifo_thread);
while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) {
int words_transferred = 0; words_transferred = 0;
while (!FIFO_EMPTY && words_transferred < 100) { while (!FIFO_EMPTY && words_transferred < 100) {
fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK];
@@ -2905,6 +2910,7 @@ fifo_thread(void *priv)
words_transferred++; words_transferred++;
} }
}
/*Only run DMA once the FIFO is empty. Required by /*Only run DMA once the FIFO is empty. Required by
Screamer 2 / Rally which will incorrectly clip an ILOAD Screamer 2 / Rally which will incorrectly clip an ILOAD
@@ -2912,7 +2918,6 @@ fifo_thread(void *priv)
if (!words_transferred) if (!words_transferred)
run_dma(mystique); run_dma(mystique);
} }
}
} }
static void static void
@@ -2962,8 +2967,6 @@ mystique_softrap_pending_timer(void *priv)
timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100);
if (thread_test_mutex(mystique->dma.lock))
{
if (mystique->endprdmasts_pending) { if (mystique->endprdmasts_pending) {
mystique->endprdmasts_pending = 0; mystique->endprdmasts_pending = 0;
mystique->status |= STATUS_ENDPRDMASTS; mystique->status |= STATUS_ENDPRDMASTS;
@@ -2976,8 +2979,9 @@ mystique_softrap_pending_timer(void *priv)
//pclog("softrapen\n"); //pclog("softrapen\n");
mystique_update_irqs(mystique); mystique_update_irqs(mystique);
} }
thread_release_mutex(mystique->dma.lock); /* Force ENDPRDMASTS flag to be set. */
} if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS))
wake_fifo_thread(mystique);
} }
static void static void