joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.65k stars 376 forks source link

Gravis Ultrasound emulation causes AGSI sysinfo program to hang #47

Open joncampbell123 opened 9 years ago

joncampbell123 commented 9 years ago

Program runs through detection routines, hangs on "Sound..." and does not proceed.

Workaround: set gus=false

joncampbell123 commented 9 years ago

Still not sure what's wrong. The program spins in an infinite loop reading and writing 0xAA to GUS DRAM byte 0.

joncampbell123 commented 9 years ago

AGSI 1.1.4 and AGSI 1.2.2 tested, same problem.

ghost commented 9 years ago

Were there any clues from the cpu log?

joncampbell123 commented 9 years ago

I single-stepped through the program with a debugger and I observed that it loads data onto the stack, calls a subroutine that writes to GUS ram, calls another subroutine that reads from GUS ram, does a compare against a byte that apparently never changes... the only suspect part of the code from that is to check that MOV instructions to/from [bp-221] works correctly from the stack segment.

ghost commented 9 years ago

I guess that could be verified against real hardware, to see whether the byte changes as expected.

joncampbell123 commented 9 years ago

I have some time now, I'll pull out an old Pentium 100MHz with a GUS and see if AGSI hangs the same way.

joncampbell123 commented 9 years ago

OK. Despite a dead CMOS battery preventing me from configuring the BIOS, I was able to bring up the Ultrasound and drivers, test that IRQ & DMA work, and then run AGSI against it. It seems to detect it OK, even though I have a SB16 PnP in an adjacent slot. However it incorrectly detects that the GUS has "0KB" of RAM. But it doesn't hang.

The operating system is Windows 95 OSR2 pure DOS mode on a CF card attached to the Pentium motherboard's IDE port.

ghost commented 9 years ago

Does it bypass the error if you try the following settings: gus=true gusrate=44100 gusbase=300 gusirq=5 gusdma=1

joncampbell123 commented 9 years ago

It does, but only because it won't probe or detect a GUS on port 300h :)

ghost commented 9 years ago

:)

I wonder if it's possible to run the debugger on real hardware and observe that the same reads and writes to gus ram and that they mirror that seen for dosbox-x.

ghost commented 9 years ago

I setup a heavy debugger version where LOG_GUS is defined. There are no logs from gus.cpp; no accesses to the gus emulation. Perhaps I could find a way to log the memory accesses.

Edit: I can't read the code overview window, but it seems like it's comparing "04" to the byte mentioned above. Is it expecting a 04 value?

3F91:11C4 C686D7FD00 mov byte [bp-0229],00 ss:[595D]=AA00 3F91:11C9 C686DEFD00 mov byte [bp-0222],00 ss:[5964]=0100 3F91:11CE 80BED7FD04 cmp byte [bp-0229],04 ss:[595D]=AA00 3F91:11D3 7603 jbe 000011D8 ($+3) (no jmp)

Edit: some info on gus detection: http://archive.gamedev.net/archive/reference/articles/article448.html http://gona.mactar.hu/GRAVIS/GF1/LINUX-10.ZIP

joncampbell123 commented 9 years ago

Really? I #defined LOG_GUS 1 and I observed the program resetting the GUS, then going into an endless loop reading/writing 0xAA to byte zero of GUS RAM.

Having LOG_GUS defined is not enough you need to change it from 0 to 1.

joncampbell123 commented 9 years ago

Actually LOG_GUS is not enough because it's written to only log on undefined register access. There is a LOG_MSG() at the top of read_gus() and write_gus() you should uncomment instead to log all I/O.

ghost commented 9 years ago

Thank you! I'll redo the tests with those changes.

ghost commented 9 years ago

The dosbox-x debugger shows the 0xAA read/writes are occuring over gus port 347.

[Redundant analysis] So, if GUS_BASE is my 0x240(gusbase) - 0x200 = 0x40, and then 347(gusport) - 0x40(GUS_BASE), then the reads and writes for 0xAA are across gus port 0x307. The lines in gus.cpp corresponding to this port are: case 0x307: if(myGUS.gDramAddr < sizeof(GUSRam)) {return GUSRam[myGUS.gDramAddr]; } else { return 0; } case 0x307: if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = (Bit8u)val; break;

Dosbox-x debugger output: Write gus port 343 val 43 Write gus port 344 val 0 Write gus port 343 val 44 Write gus port 345 val 0 Write gus port 347 val aa Write gus port 343 val 43 Write gus port 344 val 0 Write gus port 343 val 44 Write gus port 345 val 0 read from gus port 347 Write gus port 343 val 43 Write gus port 344 val 0 Write gus port 343 val 44 Write gus port 345 val 0 Write gus port 347 val aa

Is it possible to verify the gus port read/write values on real gus hardware? If there is a magic bit combination, then it may be possible to replicate that by hard-coding writes, at least temporarily to help isolate the cause.

ghost commented 9 years ago

From a link above, this seems like a common detection routine: Function GUSProbe : Boolean; Var B : Byte; Begin Port [Base+$103] := $4C; Port [Base+$105] := 0; GUSDelay; GUSDelay; Port [Base+$103] := $4C; Port [Base+$105] := 1; GUSPoke(0, $AA); GUSPoke($100, $55); B := GUSPeek(0); If B = $AA then GUSProbe := True else GUSProbe := False; End;

ghost commented 9 years ago

Tested further in dosbox-x running pure Dos with same above issue. Also, confirmed that the same, or at least similar, issue occurs in PCem, even though this it is mostly (and uniquely?) compatible with the Gus setup utilities.