From de8932643b5b74e77389e2878003b18634351ca3 Mon Sep 17 00:00:00 2001 From: Jonathan Campbell Date: Mon, 9 Jul 2018 11:34:48 -0700 Subject: [PATCH] GUS: Add hack where polling the DMA control register (when DMA unmasked and DMA TC is not signalled) automatically enables a GUS DMA transfer. This hack fixes GUS problems with ftp.scene.org/mirrors/hornet/demos/1994/m/myth_dw.zip --- src/dosbox.cpp | 5 +++++ src/hardware/gus.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 819138738b8..c3c069d6eba 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -2028,6 +2028,11 @@ void DOSBOX_SetupConfigSections(void) { "Some DOS games or demoscene productions will hang or fail to use the Ultrasound hardware\n" "because they assume the card is initialized and their hardware detect does not fully initialize the card."); + Pbool = secprop->Add_bool("dma enable on dma control polling",Property::Changeable::WhenIdle,false); + Pbool->Set_help("If set, automatically enable GUS DMA transfer bit in specific cases when the DMA control register is being polled.\n" + "THIS IS A HACK. Some games and demoscene productions need this hack to avoid hanging while uploading sample data\n" + "to the Gravis Ultrasound due to bugs in their implementation."); + Pbool = secprop->Add_bool("clear dma tc irq if excess polling",Property::Changeable::WhenIdle,false); Pbool->Set_help("If the DOS application is seen polling the IRQ status register rapidly, automatically clear the DMA TC IRQ status.\n" "This is a hack that should only be used with DOS applications that need it to avoid bugs in their GUS support code.\n" diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index ab5d83846b7..d20316639f6 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -70,6 +70,7 @@ static Bit32s AutoAmp = 512; static bool unmask_irq = false; static bool enable_autoamp = false; static bool startup_ultrinit = false; +static bool dma_enable_on_dma_control_polling = false; static Bit16u vol16bit[4096]; static Bit32u pantable[16]; static enum GUSType gus_type = GUS_CLASSIC; @@ -663,6 +664,14 @@ static Bit16u ExecuteReadRegister(void) { // NTS: The GUS SDK documents the active channel count as bits 5-0, which is wrong. it's bits 4-0. bits 7-5 are always 1 on real hardware. return ((Bit16u)(0xE0 | (myGUS.ActiveChannelsUser - 1))) << 8; case 0x41: // Dma control register - read acknowledges DMA IRQ + if (dma_enable_on_dma_control_polling) { + if (!GetDMAChannel(myGUS.dma1)->masked && !(myGUS.DMAControl & 0x01) && !(myGUS.IRQStatus & 0x80)) { + LOG(LOG_MISC,LOG_DEBUG)("GUS: As instructed, switching on DMA ENABLE upon polling DMA control register (HACK) as workaround"); + myGUS.DMAControl |= 0x01; + GUS_StartDMA(); + } + } + tmpreg = myGUS.DMAControl & 0xbf; tmpreg |= (myGUS.IRQStatus & 0x80) >> 1; myGUS.IRQStatus&=0x7f; @@ -1987,6 +1996,8 @@ class GUS:public Module_base{ startup_ultrinit = section->Get_bool("startup initialized"); + dma_enable_on_dma_control_polling = section->Get_bool("dma enable on dma control polling"); + string s_pantable = section->Get_string("gus panning table"); if (s_pantable == "default" || s_pantable == "" || s_pantable == "accurate") gus_fixed_table = true;