/* SB_Poll performs DMA transfers and fills the Direct Sound Buffer */ 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; /* FIXME: this loop must be improved */ while(!end_sound_loop) { Sleep(10); if (dma_enable) { size = DMA_Transfer(SB_DMA,min(DMATRFSIZE,SamplesCount),dma_buffer); } else continue; result = IDirectSoundBuffer_Lock(lpdsbuf,buf_off,size,(LPVOID *)&lpbuf1,&dwsize1,(LPVOID *)&lpbuf2,&dwsize2,0); if (result != DS_OK) { ERR("Unable to lock sound buffer !\n"); continue; } 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; result = IDirectSoundBuffer_Unlock(lpdsbuf,lpbuf1,dwbyteswritten1,lpbuf2,dwbyteswritten2); if (result!=DS_OK) ERR("Unable to unlock sound buffer !\n"); SamplesCount -= size; if (!SamplesCount) { DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL); dma_enable = 0; } } return 0; }
void SB_ioport_out( WORD port, BYTE val ) { switch(port) { /* DSP - Reset */ case 0x226: TRACE("Resetting DSP.\n"); SB_Reset(); break; /* DSP - Write Data or Command */ case 0x22c: TRACE("val=%x\n",val); if (command == -1) { /* Clear input buffer and set the current command */ command = val; InSize = 0; } if (InSize!=DSP_Command[command]) /* Fill the input buffer the command parameters if any */ DSP_InBuffer[InSize++]=val; else { /* Process command */ switch(command) { case 0x10: /* SB */ FIXME("Direct DAC (8-bit) - Not Implemented\n"); break; case 0x14: /* SB */ SamplesCount = DSP_InBuffer[1]+(val<<8)+1; TRACE("DMA DAC (8-bit) for %x samples\n",SamplesCount); dma_enable = 1; break; case 0x20: FIXME("Direct ADC (8-bit) - Not Implemented\n"); break; case 0x24: /* SB */ FIXME("DMA ADC (8-bit) - Not Implemented\n"); break; case 0x40: /* SB */ SampleRate = 1000000/(256-val); TRACE("Set Time Constant (%d <-> %d Hz => %d Hz)\n",DSP_InBuffer[0], SampleRate,SB_StdSampleRate(SampleRate)); SampleRate = SB_StdSampleRate(SampleRate); wav_fmt.nSamplesPerSec = SampleRate; wav_fmt.nAvgBytesPerSec = SampleRate; IDirectSoundBuffer_SetFormat(lpdsbuf,&wav_fmt); break; /* case 0xBX/0xCX -> See below */ case 0xD0: /* SB */ TRACE("Halt DMA operation (8-bit)\n"); dma_enable = 0; break; case 0xD1: /* SB */ FIXME("Enable Speaker - Not Implemented\n"); break; case 0xD3: /* SB */ FIXME("Disable Speaker - Not Implemented\n"); break; case 0xD4: /* SB */ FIXME("Continue DMA operation (8-bit) - Not Implemented\n"); break; case 0xD8: /* SB */ FIXME("Speaker Status - Not Implemented\n"); break; case 0xE0: /* SB 2.0 */ TRACE("DSP Identification\n"); DSP_OutBuffer[OutSize++] = ~val; break; case 0xE1: /* SB */ TRACE("DSP Version\n"); OutSize=2; DSP_OutBuffer[0]=0; /* returns version 1.0 */ DSP_OutBuffer[1]=1; break; case 0xF2: /* SB */ TRACE("IRQ Request (8-bit)\n"); DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL); break; default: if (((command&0xF0)==0xB0)||((DSP_InBuffer[0]&0xF0)==0xC0)) { /* SB16 */ FIXME("Generic DAC/ADC DMA (16-bit, 8-bit) - %d % d\n",command,DSP_InBuffer[1]); if (command&0x02) FIXME("Generic DAC/ADC fifo mode not supported\n"); if (command&0x04) FIXME("Generic DAC/ADC autoinit dma mode not supported\n"); if (command&0x08) FIXME("Generic DAC/ADC adc mode not supported\n"); switch(command>>4) { case 0xB: FIXME("Generic DAC/ADC 8-bit not supported\n"); SampleMode = 0; break; case 0xC: FIXME("Generic DAC/ADC 16-bit not supported\n"); SampleMode = 1; break; default: ERR("Generic DAC/ADC resolution unknown\n"); break; } if (DSP_InBuffer[1]&0x010) FIXME("Generic DAC/ADC signed sample mode not supported\n"); if (DSP_InBuffer[1]&0x020) FIXME("Generic DAC/ADC stereo mode not supported\n"); SamplesCount = DSP_InBuffer[2]+(val<<8)+1; TRACE("Generic DMA for %x samples\n",SamplesCount); dma_enable = 1; } else FIXME("DSP command %x not supported\n",val); } /* Empty the input buffer and end the command */ InSize = 0; command = -1; }
static void QueueMouseRelay(DWORD mx, DWORD my, WORD mask) { mouse_info.x = mx; mouse_info.y = my; /* Left button down */ if(mask & 0x02) { mouse_info.but |= 0x01; mouse_info.llastx = mx; mouse_info.llasty = my; mouse_info.lbcount++; } /* Left button up */ if(mask & 0x04) { mouse_info.but &= ~0x01; } /* Right button down */ if(mask & 0x08) { mouse_info.but |= 0x02; mouse_info.rlastx = mx; mouse_info.rlasty = my; mouse_info.rbcount++; } /* Right button up */ if(mask & 0x10) { mouse_info.but &= ~0x02; } /* Middle button down */ if(mask & 0x20) { mouse_info.but |= 0x04; } /* Middle button up */ if(mask & 0x40) { mouse_info.but &= ~0x04; } if ((mask & mouse_info.callmask) && mouse_info.callback) { MCALLDATA *data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MCALLDATA)); data->proc = mouse_info.callback; data->mask = mask & mouse_info.callmask; data->but = mouse_info.but; data->x = mouse_info.x; data->y = mouse_info.y; /* * Fake mickeys. * * FIXME: This is not entirely correct. If mouse if moved to the edge * of the screen, mouse will stop moving and mickeys won't * be updated even though they should be. */ data->mx = mouse_info.x * (mouse_info.HMPratio / 8); data->my = mouse_info.y * (mouse_info.VMPratio / 8); DOSVM_QueueEvent(-1, DOS_PRIORITY_MOUSE, MouseRelay, data); } }