Skip to content

Commit

Permalink
GUS: Add hack where polling the DMA control register (when DMA unmask…
Browse files Browse the repository at this point in the history
…ed 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
  • Loading branch information
joncampbell123 committed Jul 9, 2018
1 parent 34b397d commit de89326
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/dosbox.cpp
Expand Up @@ -2028,6 +2028,11 @@ void DOSBOX_SetupConfigSections(void) {
"Some DOS games or demoscene productions will hang or fail to use the Ultrasound hardware\n" "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."); "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 = 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" 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" "This is a hack that should only be used with DOS applications that need it to avoid bugs in their GUS support code.\n"
Expand Down
11 changes: 11 additions & 0 deletions src/hardware/gus.cpp
Expand Up @@ -70,6 +70,7 @@ static Bit32s AutoAmp = 512;
static bool unmask_irq = false; static bool unmask_irq = false;
static bool enable_autoamp = false; static bool enable_autoamp = false;
static bool startup_ultrinit = false; static bool startup_ultrinit = false;
static bool dma_enable_on_dma_control_polling = false;
static Bit16u vol16bit[4096]; static Bit16u vol16bit[4096];
static Bit32u pantable[16]; static Bit32u pantable[16];
static enum GUSType gus_type = GUS_CLASSIC; static enum GUSType gus_type = GUS_CLASSIC;
Expand Down Expand Up @@ -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. // 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; return ((Bit16u)(0xE0 | (myGUS.ActiveChannelsUser - 1))) << 8;
case 0x41: // Dma control register - read acknowledges DMA IRQ 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.DMAControl & 0xbf;
tmpreg |= (myGUS.IRQStatus & 0x80) >> 1; tmpreg |= (myGUS.IRQStatus & 0x80) >> 1;
myGUS.IRQStatus&=0x7f; myGUS.IRQStatus&=0x7f;
Expand Down Expand Up @@ -1987,6 +1996,8 @@ class GUS:public Module_base{


startup_ultrinit = section->Get_bool("startup initialized"); 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"); string s_pantable = section->Get_string("gus panning table");
if (s_pantable == "default" || s_pantable == "" || s_pantable == "accurate") if (s_pantable == "default" || s_pantable == "" || s_pantable == "accurate")
gus_fixed_table = true; gus_fixed_table = true;
Expand Down

0 comments on commit de89326

Please sign in to comment.