sarah-walker-pcem/pcem

SB DSP reset not properly implemented, rendering detection not working

Opened this issue · 0 comments

Describe the bug
Basically resetting the DSP should return 0AAh from the DSP when working properly. However, independent of the time waiting for the reset to be done, the value 0AAh is not returned, but 004h.

I've written SoundLib, and its reset procedure cannot detect the SB due to this routine not working properly. Note that I've tested this on real hardware, with a multitude of original SB and clone cards, and they all work the same way, returning 0AAh upon reset.
https://crossfire-designs.de/index.php?lang=de&what=sourcecode&name=sl2.htm

By the development manual from gamedev.net:
http://archive.gamedev.net/archive/reference/articles/article443.html

02x06h DSP - Reset Write SB

 DESCRIPTION
  Performs complete reset of DSP, terminating all pending operations.

 PROCEDURE
   a) Write 001h
   b) Wait 3.3жs minimum
   c) Write 000h
   d) Wait 100жs maximum for DSP Data Available (02x0Eh) 
   e) Read 0AAh from DSP Read Data (02x0Ah) <<<<<

 NOTES
  ю Reset of DSP disables speaker (see DSP command 0D3h).

To Reproduce
Here's the Pascal code to reproduce it:


procedure outp(port : word;value : byte);assembler;
asm
mov dx,port
mov al,value
out dx,al
end;

function inp(port : word) : byte;assembler;
asm
mov dx,port
in al,dx
end;

function writeDSPToAddress(address : word; v : byte) : boolean;assembler;
asm
mov dx,address
add dx,0Ch
xor cx,cx
@lp:
in al,dx
dec cx
jz @err
test al,$80
jnz @lp
jmp @Noerr
@err:
mov al,0
jmp @EnD
@Noerr:
mov al,v
out dx,al
mov al,1
@EnD:
end;

function readDSPFromAddress(address : word) : byte;assembler;
asm
mov dx,address
add dx,0Eh
xor cx,cx
@lp:
in al,dx
dec cx
jz @err
test al,$80
jz @lp
jmp @Noerr
@err:
mov al,0
jmp @EnD
@Noerr:

mov dx,address
add dx,0Ah
in al,dx
@EnD:
end;

function currenttime : longint;assembler;
asm
mov ax,0
int 1Ah
mov ax,dx
mov dx,cx
end;

function resetBlasterAtAddress(address : word) : boolean;
var
b : byte;
endtime : longint;

begin
outp(address + $6,1);
endtime := currenttime + 2;
while (endtime > currenttime) do;
outp(address + $6, 0);
b := readDSPFromAddress(address);
endtime := currenttime + 3;
repeat
b := inp(address + $E);
b := inp(address + $A);
until (b = $AA) or (currenttime >= endtime);
resetBlasterAtAddress := b = $AA;
end;

begin
writeln(resetBlasterAtAddress($220));
end.


NOTE: b is 04h every time on PCem, instead of being 0AAh, so resetting always fails.

Expected behavior
As described, 0AAh should be returned from the DSP.

Emulator configuration

  • Machine: Award SiS 496/497
  • CPU: 486DX-100
  • Graphics/sound cards: Paradise Bahamas/AWE32
  • Installed OS: MS-DOS 6.22

Additional context
Add any other context about the problem here.