Changelog: Add preliminary support for DMA and SOUNBLASTER emulation Added files: dlls/winedos/dma.h dlls/winedos/dma.c dlls/winedos/soundblaster.h dlls/winedos/soundblaster.c Modified files: dlls/winedos/ioports.c dlls/winedos/winedos.spec dlls/winedos/Makefile.in Christian Costa titan.costa@wanadoo.fr
Index: ioports.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/ioports.c,v retrieving revision 1.2 diff -u -r1.2 ioports.c --- ioports.c 9 Mar 2002 23:44:32 -0000 1.2 +++ ioports.c 10 May 2002 23:53:19 -0000 @@ -24,7 +24,8 @@ #include "windef.h" #include "dosexe.h" #include "vga.h" - +#include "soundblaster.h" +#include "dma.h" /********************************************************************** * DOSVM_inport @@ -36,10 +37,51 @@ case 0x60: *res = DOSVM_Int09ReadScan(NULL); break; + case 0x22a: + case 0x22c: + case 0x22e: + *res = (DWORD)SB_ioport_in( port ); + break; case 0x3ba: case 0x3da: *res = (DWORD)VGA_ioport_in( port ); break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0xC0: + case 0xC2: + case 0xC4: + case 0xC6: + case 0xC8: + case 0xCA: + case 0xCC: + case 0xCE: + case 0x87: + case 0x83: + case 0x81: + case 0x82: + case 0x8B: + case 0x89: + case 0x8A: + case 0x487: + case 0x483: + case 0x481: + case 0x482: + case 0x48B: + case 0x489: + case 0x48A: + case 0x08: + case 0xD0: + case 0x0D: + case 0xDA: + *res = (DWORD)DMA_ioport_in( port ); + break; default: return FALSE; /* not handled */ } @@ -57,9 +99,61 @@ case 0x20: DOSVM_PIC_ioport_out( port, (BYTE)value ); break; + case 0x226: + case 0x22c: + SB_ioport_out( port, (BYTE)value ); + break; case 0x3c8: case 0x3c9: VGA_ioport_out( port, (BYTE)value ); + break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0xC0: + case 0xC2: + case 0xC4: + case 0xC6: + case 0xC8: + case 0xCA: + case 0xCC: + case 0xCE: + case 0x87: + case 0x83: + case 0x81: + case 0x82: + case 0x8B: + case 0x89: + case 0x8A: + case 0x487: + case 0x483: + case 0x481: + case 0x482: + case 0x48B: + case 0x489: + case 0x48A: + case 0x08: + case 0xD0: + case 0x0B: + case 0xD6: + case 0x0A: + case 0xD4: + case 0x0F: + case 0xDE: + case 0x09: + case 0xD2: + case 0x0C: + case 0xD8: + case 0x0D: + case 0xDA: + case 0x0E: + case 0xDC: + DMA_ioport_out( port, (BYTE)value ); break; default: return FALSE; /* not handled */ Index: Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/winedos/Makefile.in,v retrieving revision 1.9 diff -u -r1.9 Makefile.in --- Makefile.in 9 May 2002 00:05:53 -0000 1.9 +++ Makefile.in 10 May 2002 23:53:19 -0000 @@ -24,6 +24,8 @@ ioports.c \ module.c \ vga.c \ + soundblaster.c \ + dma.c \ xms.c @MAKE_DLL_RULES@ Index: winedos.spec =================================================================== RCS file: /home/wine/wine/dlls/winedos/winedos.spec,v retrieving revision 1.9 diff -u -r1.9 winedos.spec --- winedos.spec 9 May 2002 00:05:53 -0000 1.9 +++ winedos.spec 10 May 2002 23:53:19 -0000 @@ -2,7 +2,7 @@ type win32 init DOSVM_Init -debug_channels (aspi console ddraw int int21 int31 module relay) +debug_channels (aspi console ddraw int int21 int31 module relay sblaster dma) @ stdcall LoadDosExe(str long) MZ_LoadImage
/* * DMA Emulation * * Copyright 2002 Christian Costa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __WINE_DMA_H #define __WINE_DMA_H #include "winbase.h" int DMA_Transfer(int channel,int reqlength,void* buffer); void DMA_ioport_out( WORD port, BYTE val ); BYTE DMA_ioport_in( WORD port ); #endif /* __WINE_DMA_H */
/* * DMA Emulation * * Copyright 2002 Christian Costa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Note : This is preliminary, poorly documented and not cleaned up yet */ #include "config.h" #include "windef.h" #include "dosexe.h" #include "dma.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(dma); static DWORD DMA_BaseAddress[8]; static WORD DMA_ByteCount[8]; static DWORD DMA_CurrentBaseAddress[8]; static WORD DMA_CurrentByteCount[8]; static BYTE DMA_Command[8]; static int toggle[2]={FALSE,FALSE}; int DMA_Transfer(int channel,int reqlen,void* buffer) { int size,ret=0; TRACE("DMA_Command = %x reqlen=%d\n",DMA_Command[channel],reqlen); size = (channel<4) ? 1 : 2; switch((DMA_Command[channel]&0xC)>>2) { case 0: /* Verification */ FIXME("Verification partially Implemented\n"); ret = min(DMA_CurrentByteCount[channel],reqlen) * size; break; case 1: /* Write */ ret = min(DMA_CurrentByteCount[channel],reqlen) * size; memcpy((void*)DMA_CurrentBaseAddress[channel],buffer,ret); DMA_CurrentByteCount[channel]-=ret; DMA_CurrentBaseAddress[channel]+=ret; TRACE("Perform Read transfer of %d bytes\n",ret); if (DMA_CurrentByteCount[channel]==0) TRACE("DMA buffer empty\n"); break; case 2: /* Read */ ret = min(DMA_CurrentByteCount[channel],reqlen) * size; TRACE("Perform Read transfer of %d bytes at %lx with count %x\n",ret,DMA_CurrentBaseAddress[channel], DMA_CurrentByteCount[channel]); memcpy(buffer,(void*)DMA_CurrentBaseAddress[channel],ret); DMA_CurrentByteCount[channel]-=ret; DMA_CurrentBaseAddress[channel]+=ret; if (DMA_CurrentByteCount[channel]==0) TRACE("DMA buffer empty\n"); break; case 3: /* Illegal */ ERR("Transfer Type Illegal\n"); break; } return ret; } void DMA_ioport_out( WORD port, BYTE val ) { int channel,dmachip; switch(port) { case 0x00: case 0x02: case 0x04: case 0x06: case 0xC0: case 0xC4: case 0xC8: case 0xCC: /* Base Address*/ channel = (port&0xC0)?((port-0xC0)>>2):(port>>1); dmachip = (channel<4) ? 0 : 1; if (!toggle[dmachip]) DMA_BaseAddress[channel]=(DMA_BaseAddress[channel] & ~0xFF)|(val & 0xFF); else { DMA_BaseAddress[channel]=(DMA_BaseAddress[channel] & (~(0xFF << 8)))|((val & 0xFF) << 8); DMA_CurrentBaseAddress[channel] = DMA_BaseAddress[channel]; TRACE("Write Base Address = %lx\n",DMA_BaseAddress[channel]); } toggle[dmachip] = !toggle[dmachip]; break; case 0x01: case 0x03: case 0x05: case 0x07: case 0xC2: case 0xC6: case 0xCA: case 0xCE: /* Count*/ channel = ((port-1)&0xC0)?(((port-1)-0xC0)>>2):(port>>1); dmachip = (channel<4) ? 0 : 1; if (!toggle[dmachip]) DMA_ByteCount[channel]=(DMA_ByteCount[channel] & ~0xFF)|((val+1) & 0xFF); else { DMA_ByteCount[channel]=(DMA_ByteCount[channel] & (~(0xFF << 8)))|(((val+1) & 0xFF) << 8); DMA_CurrentByteCount[channel] = DMA_ByteCount[channel]; TRACE("Write Count = %x.\n",DMA_ByteCount[channel]); } toggle[dmachip] = !toggle[dmachip]; break; case 0x87: DMA_BaseAddress[0]=(DMA_BaseAddress[0] & (~0xFF << 16))|((val & 0xFF) << 16); break; case 0x83: DMA_BaseAddress[1]=(DMA_BaseAddress[1] & (~0xFF << 16))|((val & 0xFF) << 16); break; case 0x81: DMA_BaseAddress[2]=(DMA_BaseAddress[2] & (~0xFF << 16))|((val & 0xFF) << 16); break; case 0x82: DMA_BaseAddress[3]=(DMA_BaseAddress[3] & (~0xFF << 16))|((val & 0xFF) << 16); break; case 0x8B: DMA_BaseAddress[5]=(DMA_BaseAddress[5] & (~0xFF << 16))|((val & 0xFF) << 16); break; case 0x89: DMA_BaseAddress[6]=(DMA_BaseAddress[6] & (~0xFF << 16))|((val & 0xFF) << 16); break; case 0x8A: DMA_BaseAddress[7]=(DMA_BaseAddress[7] & (~0xFF << 16))|((val & 0xFF) << 16); break; /* Low Page Base Address*/ case 0x487: DMA_BaseAddress[0]=(DMA_BaseAddress[0] & (~0xFF << 24))|((val & 0x0F) << 24); break; case 0x483: DMA_BaseAddress[1]=(DMA_BaseAddress[1] & (~0xFF << 24))|((val & 0x0F) << 24); break; case 0x481: DMA_BaseAddress[2]=(DMA_BaseAddress[2] & (~0xFF << 24))|((val & 0x0F) << 24); break; case 0x482: DMA_BaseAddress[3]=(DMA_BaseAddress[3] & (~0xFF << 24))|((val & 0x0F) << 24); break; case 0x48B: DMA_BaseAddress[5]=(DMA_BaseAddress[5] & (~0xFF << 24))|((val & 0x0F) << 24); break; case 0x489: DMA_BaseAddress[6]=(DMA_BaseAddress[6] & (~0xFF << 24))|((val & 0x0F) << 24); break; case 0x48A: DMA_BaseAddress[7]=(DMA_BaseAddress[7] & (~0xFF << 24))|((val & 0x0F) << 24); break; /* Low Page Base Address*/ case 0x08: case 0xD0: /* Command */ FIXME("Write Command (%x) - Not Implemented\n",val); break; case 0x0B: case 0xD6: /* Mode - FIXME partially implemented*/ TRACE("Write Mode (%x)\n",val); DMA_Command[((port==0xD6)?4:0)+(val&0x3)]=val; break; case 0x0A: case 0xD4: /* Write Single Mask Bit - FIXME not implemented */ TRACE("Write Single Mask Bit (%x) - Not Implemented\n",val); break; case 0x0F: case 0xDE: /* Write All Mask Bits - FIXME not implemented*/ FIXME("Write All Mask Bits (%x)\n",val); break; case 0x09: case 0xD2: /* Software DRQx Request */ FIXME("Software DRQx Request (%x) - Not Implemented\n",val); break; case 0x0C: case 0xD8: /* Reset Pointer Flip-Flop DMA */ toggle[port==0xD8]=FALSE; break; case 0x0D: case 0xDA: /* Master Reset */ FIXME("Master Reset - Not Implemented !\n"); break; case 0x0E: case 0xDC: /* Reset Mask Register */ FIXME("Reset Mask Register - Not Implemented !\n"); break; } } BYTE DMA_ioport_in( WORD port ) { int channel,dmachip; BYTE res = 0; switch(port) { case 0x00: case 0x02: case 0x04: case 0x06: case 0xC0: case 0xC4: case 0xC8: case 0xCC: /* Base Address*/ channel = (port&0xC0)?((port-0xC0)>>2):(port>>1); dmachip = (channel<4) ? 0 : 1; if (!toggle[dmachip]) res = DMA_CurrentBaseAddress[channel] & 0xFF; else { res = (DMA_CurrentBaseAddress[channel] & (0xFF << 8))>>8; TRACE("Read Current Base Address = %lx\n",DMA_CurrentBaseAddress[channel]); } toggle[dmachip] = !toggle[dmachip]; break; case 0x01: case 0x03: case 0x05: case 0x07: case 0xC2: case 0xC6: case 0xCA: case 0xCE: /* Count*/ channel = ((port-1)&0xC0)?(((port-1)-0xC0)>>2):(port>>1); dmachip = (channel<4) ? 0 : 1; if (!toggle[dmachip]) res = DMA_CurrentByteCount[channel] & 0xFF; else { res = (DMA_CurrentByteCount[channel] & (0xFF << 8))>>8; TRACE("Read Current Count = %x.\n",DMA_CurrentByteCount[channel]); } toggle[dmachip] = !toggle[dmachip]; break; case 0x87: res = (DMA_BaseAddress[0]&(0xFF<<16))>>16; break; case 0x83: res = (DMA_BaseAddress[1]&(0xFF<<16))>>16; break; case 0x81: res = (DMA_BaseAddress[2]&(0xFF<<16))>>16; break; case 0x82: res = (DMA_BaseAddress[3]&(0xFF<<16))>>16; break; case 0x8B: res = (DMA_BaseAddress[5]&(0xFF<<16))>>16; break; case 0x89: res = (DMA_BaseAddress[6]&(0xFF<<16))>>16; break; case 0x8A: res = (DMA_BaseAddress[7]&(0xFF<<16))>>16; break; /* Low Page Base Address*/ case 0x487: res = (DMA_BaseAddress[0]&(0xFF<<24))>>24; break; case 0x483: res = (DMA_BaseAddress[1]&(0xFF<<24))>>24; break; case 0x481: res = (DMA_BaseAddress[2]&(0xFF<<24))>>24; break; case 0x482: res = (DMA_BaseAddress[3]&(0xFF<<24))>>24; break; case 0x48B: res = (DMA_BaseAddress[5]&(0xFF<<24))>>24; break; case 0x489: res = (DMA_BaseAddress[6]&(0xFF<<24))>>24; break; case 0x48A: res = (DMA_BaseAddress[7]&(0xFF<<24))>>24; break; /* High Page Base Address*/ case 0x08: case 0xD0: /* Status */ case 0x0D: case 0xDA: /* Temporary */ break; } return res; }
/* * Soundblaster Emulation * * Copyright 2002 Christian Costa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __WINE_SOUNDBLASTER_H #define __WINE_SOUNDBLASTER_H #include "winbase.h" void SB_ioport_out( WORD port, BYTE val ); BYTE SB_ioport_in( WORD port ); #endif /* __WINE_SOUNDBLASTER_H */
/* * Soundblaster Emulation * * Copyright 2002 Christian Costa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Note : This is preliminary, poorly documented and not cleaned up yet */ #include "config.h" #include "windef.h" #include "dosexe.h" #include "soundblaster.h" #include "wine/debug.h" #include "dsound.h" #include "dma.h" WINE_DEFAULT_DEBUG_CHANNEL(sblaster); static int SampleRate; static int SamplesCount; static BYTE DSP_Command[256]; static BYTE DSP_Buffer[10]; static int data; static int order = 0; static int resval = 0; static int end_loop = 0; static int start = 0; typedef HRESULT (WINAPI* fnDirectSoundCreate) (LPGUID,LPDIRECTSOUND*,LPUNKNOWN); fnDirectSoundCreate lpDirectSoundCreate; static HANDLE SB_Thread; static HMODULE hmodule; static LPDIRECTSOUND lpdsound; static LPDIRECTSOUNDBUFFER lpdsbuf; static DSBUFFERDESC buf_desc; static WAVEFORMATEX wav_fmt; static UINT buf_off; static BYTE dma_buffer[65536*2]; extern HWND vga_hwnd; #define DSBUFLEN 4096 #define SB_IRQ 5 #define SB_IRQ_PRI 11 #define SB_DMA 1 static void SB_CleanBuffer() { HRESULT result; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD dwbyteswritten1 = 0; DWORD dwbyteswritten2 = 0; int i; result = IDirectSoundBuffer_Lock(lpdsbuf,0,DSBUFLEN,&lpbuf1,&dwsize1,&lpbuf2,&dwsize2,0); for(i=0;i<dwsize1;i++) *(lpbuf1+i) = 0; for(i=0;i<dwsize2;i++) *(lpbuf2+i) = 0; result = IDirectSoundBuffer_Unlock(lpdsbuf,lpbuf1,dwbyteswritten1,lpbuf2,dwbyteswritten2); } static DWORD CALLBACK SB_Poll( void *dummy ) { HRESULT result; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD dwbyteswritten1 = 0; DWORD dwbyteswritten2 = 0; int size; while(!end_loop) { Sleep(10); #define B1 #ifdef B1 if (start) { int reqsize; reqsize = 1024; size = DMA_Transfer(SB_DMA,reqsize,dma_buffer); SamplesCount -= size; if (!SamplesCount) { DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL); start = 0; } } else continue; #else if (!start) continue; #endif result = IDirectSoundBuffer_Lock(lpdsbuf,buf_off,size,&lpbuf1,&dwsize1,&lpbuf2,&dwsize2,0); #ifndef B1 size = DMA_Transfer(SB_DMA,dwsize1+dwsize2,dma_buffer); if (!size) goto end; #endif SamplesCount -= size; if (!SamplesCount) { DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL); start = 0; } dwbyteswritten1 = min(size,dwsize1); memcpy(lpbuf1,dma_buffer,dwbyteswritten1); if (size>dwsize1) { dwbyteswritten2 = min(size - dwbyteswritten1,dwsize2); memcpy(lpbuf2,dma_buffer+dwbyteswritten1,dwbyteswritten2); } buf_off = (buf_off + dwbyteswritten1 + dwbyteswritten2) % DSBUFLEN; #ifndef B1 end: #endif result = IDirectSoundBuffer_Unlock(lpdsbuf,lpbuf1,dwbyteswritten1,lpbuf2,dwbyteswritten2); } return 0; } void SB_Init() { HRESULT result; if (!lpdsound) { hmodule = LoadLibraryA("dsound.dll"); if (!hmodule) { ERR("Can't load dsound.dll !\n"); return; } lpDirectSoundCreate = (fnDirectSoundCreate)GetProcAddress(hmodule,"DirectSoundCreate"); if (!lpDirectSoundCreate) { /* CloseHandle(hmodule); */ ERR("Can't find DirectSoundCreate function !\n"); return; } result = (*lpDirectSoundCreate)(NULL,&lpdsound,NULL); if (result != DS_OK) { ERR("Unable to initialize Sound Subsystem err = %lx !\n",result); return; } result = IDirectSound_SetCooperativeLevel(lpdsound,vga_hwnd,DSSCL_EXCLUSIVE|DSSCL_PRIORITY); if (result != DS_OK) { ERR("Can't set cooperative level !\n"); return; } /* Default format */ wav_fmt.wFormatTag = WAVE_FORMAT_PCM; wav_fmt.nChannels = 1; wav_fmt.nSamplesPerSec = 22050; wav_fmt.nAvgBytesPerSec = 22050; wav_fmt.nBlockAlign = 1; wav_fmt.wBitsPerSample = 8; wav_fmt.cbSize = 0; memset(&buf_desc,0,sizeof(DSBUFFERDESC)); buf_desc.dwSize = sizeof(DSBUFFERDESC); buf_desc.dwBufferBytes = DSBUFLEN; buf_desc.lpwfxFormat = &wav_fmt; result = IDirectSound_CreateSoundBuffer(lpdsound,&buf_desc,&lpdsbuf,NULL); if (result != DS_OK) { ERR("Can't create sound buffer !\n"); return; } SB_CleanBuffer(); result = IDirectSoundBuffer_Play(lpdsbuf,0, 0, DSBPLAY_LOOPING); if (result != DS_OK) { ERR("Can't start playing !\n"); return; } buf_off = 0; end_loop = 0; SB_Thread = CreateThread(NULL, 0, SB_Poll, NULL, 0, NULL); TRACE("thread\n"); if (!SB_Thread) { ERR("Can't create thread !\n"); return; } } resval = 0xaa; } void SB_Reset() { int i; for(i=0;i<256;i++) DSP_Command[i]=0; /* Set Time Constant */ DSP_Command[0x40]=1; /* Generate IRQ */ DSP_Command[0xf2]=0; /* DMA DAC 8-bits */ DSP_Command[0x14]=2; SB_Init(); } int SB_StdSampleRate(int SampleRate) { if (SampleRate>((44100+48000)/2)) return 48000; if (SampleRate>((32000+44100)/2)) return 44100; if (SampleRate>((24000+32000)/2)) return 32000; if (SampleRate>((22050+24000)/2)) return 24000; if (SampleRate>((16000+22050)/2)) return 22050; if (SampleRate>((12000+16000)/2)) return 16000; if (SampleRate>((11025+12000)/2)) return 12000; if (SampleRate>((8000+11025)/2)) return 11025; return 8000; } void SB_ioport_out( WORD port, BYTE val ) { switch(port) { case 0x226: TRACE("Resetting DSP.\n"); SB_Reset(); break; case 0x22c: if (!order) { order = val; data = 0; } if (data!=DSP_Command[order]) DSP_Buffer[data++]=val; else { switch(order) { case 0x14: SamplesCount = DSP_Buffer[1]+(val<<8)+1; TRACE("DMA DAC 8-bits for %x samples - Not Implemented\n",SamplesCount); start = 1; break; case 0x40: SampleRate = 1000000/(256-val); TRACE("Set Time Constant (%d <-> %d Hz => %d Hz)\n",DSP_Buffer[0], SampleRate,SB_StdSampleRate(SampleRate)); SampleRate = SB_StdSampleRate(SampleRate); wav_fmt.nSamplesPerSec = SampleRate; wav_fmt.nAvgBytesPerSec = SampleRate; IDirectSoundBuffer_SetFormat(lpdsbuf,&wav_fmt); break; case 0xD0: TRACE("Halt DMA 8-bits operation\n"); start = 0; break; case 0xD1: FIXME("Enable Speaker - Not Implemented\n"); break; case 0xD3: FIXME("Disable Speaker - Not Implemented\n"); break; case 0xf2: TRACE("Generate IRQ\n"); DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL); break; default: FIXME("DSP command %x not supported\n",val); } order = 0; } } } BYTE SB_ioport_in( WORD port ) { BYTE res = 0; switch(port) { case 0x22a: /* Value after a RESET */ res = 0xaa; //resval; break; case 0x22c: /* DSP always ready for writing */ res = 0x00; break; case 0x22e: /* DSP data to read */ res = 0x80; break; } return res; }