00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1993 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ SB.C 00007 Nombre paquete............... - 00008 Lenguaje fuente.............. C (Borland C/C++ 3.1) 00009 Estado....................... Completado 00010 Dependencia Hard/OS.......... Sound Blaster 00011 Codigo condicional........... DSP_GET_DOUBLE_RATE 00012 00013 Codificacion................. Borja Etxebarria 00014 00015 Version dd/mm/aa Autor Proposito de la edicion 00016 ------- -------- -------- ----------------------- 00017 1.1.0 03/03/95 Borja funciones IRQ_ack_??? 00018 1.0.0 19/02/94 Borja Codificacion inicial. 00019 00020 ======================== Contenido ======================== 00021 Primitivas basicas para tarjetas SoundBlaster. 00022 00023 La SB16 soporta comandos de las tarjetas anteriores, 00024 pero se recomienda usar sb_DSP_16() y sb_DSP_8() para 00025 grabar/reproducir. 00026 00027 Si DSP_GET_DOUBLE_RATE esta definido, se genera la 00028 funcion sb_DSP_tc2dsr() que utiliza numeros en coma 00029 flotante. 00030 .................... 00031 Basic primitives for SoundBlaster cards. 00032 00033 SB16 supports commands from previous SB cards, but the 00034 recommended commands to play/rec are sb_DSP_16() and sb_DSP_8(). 00035 00036 If DSP_GET_DOUBLE_RATE is defined, the function 00037 sb_DSP_tc2dsr() is generated. This function uses floating 00038 point numbers. 00039 =========================================================== 00040 */ 00041 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00042 /**********************************************************/ 00043 00044 #include "sb.h" 00045 00046 #include "ports.h" /* leer/escribir puertos */ 00047 00048 /**********************************************************/ 00049 /* numero maximo de reintentos en operaciones con el DSP. 00050 Debe entrar en un UINT16 */ 00051 00052 #define DSP_TEST_LOOPS 0xFFFF 00053 00054 /**********************************************************/ 00055 /* registros del DSP */ 00056 #define DSP_REG_RESET (_sb_baseport+0x06) 00057 #define DSP_REG_RDATA (_sb_baseport+0x0A) 00058 #define DSP_REG_RSTATUS (_sb_baseport+0x0E) 00059 #define DSP_REG_WDATA (_sb_baseport+0x0C) 00060 #define DSP_REG_WSTATUS (_sb_baseport+0x0C) 00061 00062 /* respuesta del DSP al hacer un reset */ 00063 #define DSP_READY 0xAA 00064 /* mascara para comprobar si se puede enviar dato al DSP */ 00065 #define DSP_MASK_BUSY 0x80 00066 /* mascara para comprobar si se puede leer dato del DSP */ 00067 #define DSP_MASK_DATA_AVAIL 0x80 00068 00069 /* informacion del mixer, necesaria para ACK de interrupcion al DSP */ 00070 #define MIX_REG_ADDR (_sb_baseport+0x04) 00071 #define MIX_REG_DATA (_sb_baseport+0x05) 00072 #define MIX_ADDR_IRQ_STAT 0x82 00073 00074 /* leer en estos registros para enviar ACK para el DSP, 00075 en funcion de las diversas interrupciones posibles */ 00076 #define DSP_REG_IRQ_ACK_DMA8MIDI DSP_REG_RSTATUS 00077 #define DSP_REG_IRQ_ACK_DMA16 (_sb_baseport+0x0F) 00078 #define DSP_REG_IRQ_ACK_MPU (_sb_baseport+0x10) 00079 00080 /**********************************************************/ 00081 /* no hace nada, solo para perder tiempo al resetear el DSP 00082 .................... 00083 iddle function to wait a little time*/ 00084 00085 VOID do_nothing( VOID ) 00086 { 00087 } 00088 00089 /**********************************************************/ 00090 /* lee y {devuelve} dato del DSP (es un byte), 00091 o {devuelve} un 0xFFFF (DSP_ERROR) en caso de error 00092 .................... 00093 {returns} a data byte from the DSP. 00094 {returns} 0xFFFF (DSP_ERROR) if error. */ 00095 00096 UINT16 sb_DSP_read( UINT16 _sb_baseport ) 00097 { 00098 UINT16 i; 00099 00100 for (i=DSP_TEST_LOOPS; i; i--) { 00101 if ((INPORT8(DSP_REG_RSTATUS)&DSP_MASK_DATA_AVAIL) != 0) 00102 return INPORT8(DSP_REG_RDATA); 00103 } 00104 00105 return DSP_ERROR; 00106 } 00107 00108 /**********************************************************/ 00109 /* resetea el DSP. {devuelve} DSP_ERROR (0xFFFF) en caso de error, 00110 o 0 si todo va bien. 00111 .................... 00112 resets the DSP. {returs} DSP_ERROR (0xFFFF) if error, or 0 if 00113 reset is correctly performed */ 00114 00115 UINT16 sb_DSP_reset( UINT16 _sb_baseport ) 00116 { 00117 UINT16 i; 00118 UINT16 data; 00119 00120 OUTPORT8(DSP_REG_RESET,0x01); 00121 for (i=DSP_TEST_LOOPS; i; i--) /* perder tiempo */ 00122 do_nothing(); 00123 OUTPORT8(DSP_REG_RESET,0x00); 00124 00125 for (i=DSP_TEST_LOOPS; i; i--) { 00126 data = sb_DSP_read(_sb_baseport); 00127 if (data==DSP_READY) 00128 return 0; 00129 } 00130 00131 return DSP_ERROR; 00132 } 00133 00134 /**********************************************************/ 00135 /* escribe en el dsp el dato o comando enviado en el byte {data}. 00136 La funcion {devuelve} 0 si tiene exito, o DSP_ERROR (0xFFFF) en 00137 caso de error 00138 .................... 00139 writes a data byte {data} to the DSP (data or command). 00140 The function {returns} 0 if succeeds, or DSP_ERROR (0xFFFF) on 00141 error */ 00142 00143 UINT16 sb_DSP_write( UINT16 _sb_baseport, UINT8 data ) 00144 { 00145 UINT16 i; 00146 00147 for (i=DSP_TEST_LOOPS; i; i--) { 00148 if ((INPORT8(DSP_REG_WSTATUS)&DSP_MASK_BUSY) == 0) { 00149 OUTPORT8(DSP_REG_WDATA,data); 00150 return 0; 00151 } 00152 } 00153 00154 return DSP_ERROR; 00155 } 00156 00157 /**********************************************************/ 00158 /* {devuelve} el registro de estado de interrupciones de la SB16, 00159 necesario para saber quien ha producido la interrupcion. 00160 00161 bit 0: DMA 8 bits o MIDI 00162 bit 1: DMA 16 bits 00163 bit 2: MPU 00164 00165 Estos bits estan definidos en las mascaras: 00166 00167 DSP_MASK_IRQ_DMA8MIDI 00168 DSP_MASK_IRQ_DMA16 00169 DSP_MASK_IRQ_MPU 00170 00171 el ack de la interrupcion se debe hace en funcion del causante de 00172 ella, leyendo el puerto definido para cada caso como: 00173 00174 DSP_REG_IRQ_ACK_DMA8MIDI 00175 DSP_REG_IRQ_ACK_DMA16 00176 DSP_REG_IRQ_ACK_MPU 00177 00178 Como DMA8 y MIDI usan el mismo bit, no se deben utilizar simultaneamente. 00179 00180 Version DSP >= 4.0 00181 .................... 00182 {returns} the SB16 interrupt status register, needed to know the 00183 interrupt reason: 00184 00185 bit 0: DMA 8 or MIDI 00186 bit 1: DMA 16 00187 bit 2: MPU 00188 00189 These bits are defined with this masks (#define): 00190 00191 DSP_MASK_IRQ_DMA8MIDI 00192 DSP_MASK_IRQ_DMA16 00193 DSP_MASK_IRQ_MPU 00194 00195 the interrupt ACK should be send acording to the reason who produced 00196 it. The ACK for each of the three reasons previously defined is sent 00197 reading respectively the port: 00198 00199 DSP_REG_IRQ_ACK_DMA8MIDI 00200 DSP_REG_IRQ_ACK_DMA16 00201 DSP_REG_IRQ_ACK_MPU 00202 00203 As DMA8 and MIDI use the same interrupt status bit, there is no 00204 way to diferentiate them, so you shuld never perform simultaneous DMA8 00205 and MIDI operations. 00206 00207 DSP version >= 4.0 */ 00208 00209 UINT8 sb_IRQ_stat( UINT16 _sb_baseport ) 00210 { 00211 OUTPORT8(MIX_REG_ADDR,MIX_ADDR_IRQ_STAT); 00212 return INPORT8(MIX_REG_DATA); 00213 } 00214 00215 /**********************************************************/ 00216 /* envia un ACK al DSP para la interrupcion pendiente, sea del 00217 tipo que sea. 00218 .................... 00219 Sends an ACK to the DSP for a received interrupt signal. 00220 The function selects the correct interrupt reason(s) and sends 00221 the correct ACK signal(s)*/ 00222 00223 VOID sb_IRQ_ack( UINT16 _sb_baseport ) 00224 { 00225 UINT8 irqstat = sb_IRQ_stat(_sb_baseport); 00226 00227 if (irqstat & DSP_MASK_IRQ_DMA8MIDI) 00228 INPORT8(DSP_REG_IRQ_ACK_DMA8MIDI); 00229 00230 if (irqstat & DSP_MASK_IRQ_DMA16) 00231 INPORT8(DSP_REG_IRQ_ACK_DMA16); 00232 00233 if (irqstat & DSP_MASK_IRQ_MPU) 00234 INPORT8(DSP_REG_IRQ_ACK_DMA16); 00235 } 00236 00237 /**********************************************************/ 00238 /* envia un ACK al DSP para la interrupcion de tipo DMA8-MIDI 00239 .................... 00240 Sends an ACK to the DSP for an interrupt of tye DMA8-MIDI */ 00241 00242 VOID sb_IRQ_ack_dma8midi( UINT16 _sb_baseport ) 00243 { 00244 INPORT8(DSP_REG_IRQ_ACK_DMA8MIDI); 00245 } 00246 00247 /**********************************************************/ 00248 /* envia un ACK al DSP para la interrupcion de tipo DMA16 00249 .................... 00250 Sends an ACK to the DSP for an interrupt of tye DMA16 */ 00251 00252 VOID sb_IRQ_ack_dma16( UINT16 _sb_baseport ) 00253 { 00254 INPORT8(DSP_REG_IRQ_ACK_DMA16); 00255 } 00256 00257 /**********************************************************/ 00258 /* envia un ACK al DSP para la interrupcion de tipo MPU 00259 .................... 00260 Sends an ACK to the DSP for an interrupt of tye MPU */ 00261 00262 VOID sb_IRQ_ack_mpu( UINT16 _sb_baseport ) 00263 { 00264 INPORT8(DSP_REG_IRQ_ACK_DMA16); 00265 } 00266 00267 /**********************************************************/ 00268 /* Comando DSP 10h. 00269 Escribe directamente una muestra de 8 bits, enviada en {sample_val}. 00270 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00271 version DSP 1.xx, 2.0, 2.01x, 3.xx, 4.xx 00272 .................... 00273 DSP command 10h. 00274 Directly writes an 8 bit sample {sample_val}. 00275 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00276 DSP version 1.xx, 2.0, 2.01x, 3.xx, 4.xx */ 00277 00278 UINT16 sb_DSP_out8( UINT16 _sb_baseport, UINT8 sample_val ) 00279 { 00280 if (sb_DSP_write(_sb_baseport,0x10) == DSP_ERROR) 00281 return DSP_ERROR; 00282 00283 return sb_DSP_write(_sb_baseport,sample_val); 00284 } 00285 00286 /**********************************************************/ 00287 /* Comando DSP 14h. 00288 Conversion D/A PCM de 8 bits por DMA (de 8 bits), utilizando el 00289 modo de ciclo unico. Se reproducen {samples_minus_1}+1 muestras de 00290 8 bits cada una de ellas. 00291 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00292 version DSP >= 1.0 00293 .................... 00294 DSP command 14h. 00295 PCM 8 bit D/A conversion using DMA 8, in single cicle mode. 00296 The SB will play {sample_minus_1}+1 samples (8 bit each). 00297 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00298 DSP version >= 1.0 */ 00299 00300 UINT16 sb_DSP_dma_out8_single( UINT16 _sb_baseport, UINT16 samples_minus_1 ) 00301 { 00302 if (sb_DSP_write(_sb_baseport,0x14) == DSP_ERROR) 00303 00304 return DSP_ERROR; 00305 if (sb_DSP_write(_sb_baseport,(UINT8)samples_minus_1) == DSP_ERROR) 00306 return DSP_ERROR; 00307 return sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1>>8)); 00308 } 00309 00310 /**********************************************************/ 00311 /* Comando DSP 1Ch. 00312 Conversion D/A PCM de 8 bits por DMA (de 8 bits), utilizando el 00313 modo de autoinicializacion. 00314 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00315 version DSP >= 2.0 00316 .................... 00317 DSP command 1Ch. 00318 PCM 8 bit D/A conversion using DMA 8, in autoinit mode. 00319 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00320 DSP version >= 2.0 */ 00321 00322 UINT16 sb_DSP_dma_out8_auto( UINT16 _sb_baseport ) 00323 { 00324 return sb_DSP_write(_sb_baseport,0x1C); 00325 } 00326 00327 /**********************************************************/ 00328 /* Comando DSP 20h. 00329 Lee y {devuelve} directamente una muestra de 8 bits. 00330 {devuelve} DSP_ERROR (0xFFFF) si error. 00331 version DSP 1.xx, 2.0, 2.01x, 3.xx, 4.xx 00332 .................... 00333 DSP command 20h. 00334 Directly reads and {returns} an 8 bit sample. 00335 {returns} DSP_ERROR (0xFFFF) if error. 00336 DSP version 1.xx, 2.0, 2.01x, 3.xx, 4.xx */ 00337 00338 UINT16 sb_DSP_in8( UINT16 _sb_baseport ) 00339 { 00340 if (sb_DSP_write(_sb_baseport,0x20) == DSP_ERROR) 00341 return DSP_ERROR; 00342 00343 return sb_DSP_read(_sb_baseport); 00344 } 00345 00346 /**********************************************************/ 00347 /* Comando DSP 24h. 00348 Conversion A/D PCM de 8 bits por DMA (de 8 bits), utilizando el 00349 modo de ciclo unico. Se graban {samples_minus_1}+1 muestras de 00350 8 bits cada una de ellas. 00351 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00352 version DSP >= 1.0 00353 .................... 00354 DSP command 24h. 00355 PCM 8 bit A/D conversion using DMA 8, in single cicle mode. 00356 The SB will record {sample_minus_1}+1 samples (8 bit each). 00357 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00358 DSP version >= 1.0 */ 00359 00360 UINT16 sb_DSP_dma_in8_single( UINT16 _sb_baseport, UINT16 samples_minus_1 ) 00361 { 00362 if (sb_DSP_write(_sb_baseport,0x24) == DSP_ERROR) 00363 return DSP_ERROR; 00364 if (sb_DSP_write(_sb_baseport,(UINT8)samples_minus_1) == DSP_ERROR) 00365 return DSP_ERROR; 00366 return sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1 >> 8)); 00367 } 00368 00369 /**********************************************************/ 00370 /* Comando DSP 2Ch. 00371 Conversion A/D PCM de 8 bits por DMA (de 8 bits), utilizando el 00372 modo de autoinicializacion. 00373 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00374 version DSP >= 2.0 00375 .................... 00376 DSP command 2Ch. 00377 PCM 8 bit A/D conversion using DMA 8, in autoinit mode. 00378 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00379 DSP version >= 2.0 */ 00380 00381 UINT16 sb_DSP_dma_in8_auto( UINT16 _sb_baseport ) 00382 { 00383 return sb_DSP_write(_sb_baseport,0x2C); 00384 } 00385 00386 /**********************************************************/ 00387 /* {devuelve} la constante de tiempo a utilizar para tener 00388 la frecuencia de muestreo mas aproximada a {sampling_rate} 00389 si se utilizan {channels} canales (1=mono, 2=stereo) 00390 .................... 00391 {returns} the time constant that must be used to select 00392 the sampling rate nearest to {sampling_rate}, if the SBlaster 00393 will play/record {channels} audio channels (1=mono, 2=stereo) */ 00394 00395 UINT8 sb_DSP_sr2tc( UINT16 sampling_rate, UINT8 channels ) 00396 { 00397 return ((65536L - 256000000L / ((UINT32)sampling_rate * channels)) >> 8); 00398 } 00399 00400 /**********************************************************/ 00401 /* {devuelve} la frecuencia de muestreo resultante de utilizar 00402 la constante de tiempo {time_constant} si se utilizan 00403 {channels} canales (1=mono, 2=stereo) 00404 .................... 00405 {returns} the used sampling rate when {time_constant} is used 00406 as the time constant, and the SBlaster will play/record {channels} 00407 audio channels (1=mono, 2=stereo). */ 00408 00409 UINT16 sb_DSP_tc2sr( UINT8 time_constant, UINT8 channels ) 00410 { 00411 return (UINT16)((256000000L / (65536L - ((UINT16)time_constant << 8))) / 00412 channels); 00413 } 00414 00415 /**********************************************************/ 00416 /* Similar a sb_DSP_tc2sr(), pero la frecuencia que se 00417 {devuelve} es exacta (un numero real). 00418 Solo si DSP_GET_DOUBLE_RATE esta definido 00419 .................... 00420 This function is similar to sb_DSP_tc2sr(), but the {returned} 00421 sampling rate is a more precise value (a floating point number). 00422 This function is defined only if DSP_GET_DOUBLE_RATE is defined, 00423 so as to easily avoid linking floating point math if you don't 00424 need it. */ 00425 00426 #ifdef DSP_GET_DOUBLE_RATE 00427 00428 DOUBLE sb_DSP_tc2dsr( UINT8 time_constant, UINT8 channels ) 00429 { 00430 return (1000000.0 / (256 - time_constant) / channels); 00431 } 00432 00433 #endif 00434 00435 /**********************************************************/ 00436 /* Comando DSP 40h. 00437 Selecciona la constante de tiempo {time_constant} para la 00438 frecuencia de muestreo en operaciones AD/DA. 00439 Utiliza sb_DSP_sr2tc() para calcular la constante de tiempo 00440 a partir de la frecuencia de muestro (Hz). 00441 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00442 version DSP >= 1.0 00443 .................... 00444 DSP command 40h. 00445 Programs the time constant {time_constant} to select the 00446 sampling rate in AD/DA conversion. 00447 Use sb_DSP_sr2tc() to convert the sampling rate (Hz) to time 00448 constant. 00449 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00450 DSP version >= 1.0 */ 00451 00452 UINT16 sb_DSP_tconst( UINT16 _sb_baseport, UINT8 time_constant ) 00453 { 00454 if (sb_DSP_write(_sb_baseport,0x40) == DSP_ERROR) 00455 return DSP_ERROR; 00456 return sb_DSP_write(_sb_baseport,time_constant); 00457 } 00458 00459 /**********************************************************/ 00460 /* Comando DSP 41h. 00461 Selecciona la frecuencia de muestreo {sampling_rate} para D/A. 00462 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00463 version DSP 4.xx 00464 .................... 00465 DSP command 41h. 00466 Selects the sampling rate {sampling_rate} for D/A. 00467 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00468 DSP version 4.xx */ 00469 00470 UINT16 sb_DSP_out_rate( UINT16 _sb_baseport, UINT16 sampling_rate ) 00471 { 00472 #ifdef __SHAREWARE_VERSION__ 00473 sampling_rate = 1000; 00474 sampling_rate +=500; 00475 sampling_rate *= 5; /* 7500 Hz, shareware */ 00476 #endif 00477 00478 if (sb_DSP_write(_sb_baseport,0x41) == DSP_ERROR) 00479 return DSP_ERROR; 00480 if (sb_DSP_write(_sb_baseport,(UINT8)(sampling_rate >> 8)) == DSP_ERROR) 00481 return DSP_ERROR; 00482 return sb_DSP_write(_sb_baseport,(UINT8)sampling_rate); 00483 } 00484 00485 /**********************************************************/ 00486 /* Comando DSP 42h. 00487 Selecciona la frecuencia de muestreo {sampling_rate} para A/D. 00488 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00489 version DSP 4.xx 00490 .................... 00491 DSP command 42h. 00492 Selects the sampling rate {sampling_rate} for A/D. 00493 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00494 DSP version 4.xx */ 00495 00496 UINT16 sb_DSP_in_rate( UINT16 _sb_baseport, UINT16 sampling_rate ) 00497 { 00498 #ifdef __SHAREWARE_VERSION__ 00499 sampling_rate = 1000; 00500 sampling_rate +=500; 00501 sampling_rate *= 5; /* 7500 Hz, shareware */ 00502 #endif 00503 00504 if (sb_DSP_write(_sb_baseport,0x42) == DSP_ERROR) 00505 return DSP_ERROR; 00506 if (sb_DSP_write(_sb_baseport,(UINT8)(sampling_rate >> 8)) == DSP_ERROR) 00507 return DSP_ERROR; 00508 return sb_DSP_write(_sb_baseport,(UINT8)sampling_rate); 00509 } 00510 00511 /**********************************************************/ 00512 /* Comando DSP 48h. 00513 Selecciona la longitud {block_transfer_size_minus_1} en bytes del 00514 bloque de transferencia. El DSP genera una interrupcion cada tal 00515 numero de bytes. 00516 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00517 version DSP 2.00, 2.01+, 2.xx, 4.xx 00518 .................... 00519 DSP command 48h. 00520 Programs the block transfer length in bytes. Send the length-1 00521 in {block_transfer_size_minus_1}. The DSP raises an interrupt 00522 for each block transferred. 00523 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00524 DSP version 2.00, 2.01+, 2.xx, 4.xx */ 00525 00526 UINT16 sb_DSP_blk_size( UINT16 _sb_baseport, UINT16 block_transfer_size_minus_1 ) 00527 { 00528 if (sb_DSP_write(_sb_baseport,0x48) == DSP_ERROR) 00529 return DSP_ERROR; 00530 if (sb_DSP_write(_sb_baseport,(UINT8)block_transfer_size_minus_1) == DSP_ERROR) 00531 return DSP_ERROR; 00532 return sb_DSP_write(_sb_baseport,(UINT8)(block_transfer_size_minus_1 >> 8)); 00533 } 00534 00535 /**********************************************************/ 00536 /* Comando DSP 80h. 00537 Silencio en conversion D/A durante {samples_minus_1} muestras. 00538 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00539 version DSP 1.xx, 2.00, 2.01+, 2.xx, 4.xx 00540 .................... 00541 DSP command 80h. 00542 Performs a silence D/A playback of {samples_minus_1} samples. 00543 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00544 DSP version 1.xx, 2.00, 2.01+, 2.xx, 4.xx */ 00545 00546 UINT16 sb_DSP_out_silence( UINT16 _sb_baseport, UINT16 samples_minus_1 ) 00547 { 00548 if (sb_DSP_write(_sb_baseport,0x80) == DSP_ERROR) 00549 return DSP_ERROR; 00550 if (sb_DSP_write(_sb_baseport,(UINT8)samples_minus_1) == DSP_ERROR) 00551 return DSP_ERROR; 00552 return sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1 >> 8)); 00553 } 00554 00555 /**********************************************************/ 00556 /* Comando DSP 90h. 00557 Conversion D/A PCM de 8 bits de alta velocidad por DMA (de 8 bits), 00558 utilizando el modo de autoinicializacion. 00559 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00560 version DSP 2.01+, 3.xx 00561 .................... 00562 DSP command 90h. 00563 High speed DMA D/A conversion (PCM 8 bit), using autoinitialize 00564 mode. 00565 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00566 DSP version 2.01+, 3.xx */ 00567 00568 UINT16 sb_DSP_dma_out8hs_auto( UINT16 _sb_baseport ) 00569 { 00570 return sb_DSP_write(_sb_baseport,0x90); 00571 } 00572 00573 /**********************************************************/ 00574 /* Comando DSP 91h. 00575 Conversion D/A PCM de 8 bits de alta velocidad por DMA (de 8 bits), 00576 utilizando el modo de ciclo unico. Se reproducen tantas muestras como 00577 se hayan indicado con el comando 48h. 00578 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00579 version DSP 2.01+, 3.xx 00580 .................... 00581 DSP command 91h. 00582 High speed DMA D/A conversion (PCM 8 bit), using single ciclye mode. 00583 The number of samples to play must be previously programmed using 00584 command 48h. 00585 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00586 DSP version 2.01+, 3.xx */ 00587 00588 UINT16 sb_DSP_dma_out8hs_single( UINT16 _sb_baseport ) 00589 { 00590 return sb_DSP_write(_sb_baseport,0x91); 00591 } 00592 00593 /**********************************************************/ 00594 /* Comando DSP 98h. 00595 Conversion A/D PCM de 8 bits de alta velocidad por DMA (de 8 bits), 00596 utilizando el modo de autoinicializacion. 00597 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00598 version DSP 2.01+, 3.xx 00599 .................... 00600 DSP command 98h. 00601 High speed DMA A/D conversion (PCM 8 bit), using autoinitialize 00602 mode. 00603 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00604 DSP version 2.01+, 3.xx */ 00605 00606 UINT16 sb_DSP_dma_in8hs_auto( UINT16 _sb_baseport ) 00607 { 00608 return sb_DSP_write(_sb_baseport,0x98); 00609 } 00610 00611 /**********************************************************/ 00612 /* Comando DSP 99h. 00613 Conversion A/D PCM de 8 bits de alta velocidad por DMA (de 8 bits), 00614 utilizando el modo de ciclo unico. Se graban tantas muestras como 00615 se hayan indicado con el comando 48h. 00616 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00617 version DSP 2.01+, 3.xx 00618 .................... 00619 DSP command 99h. 00620 High speed DMA A/D conversion (PCM 8 bit), using single ciclye mode. 00621 The number of samples to record must be previously programmed using 00622 command 48h. 00623 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00624 DSP version 2.01+, 3.xx */ 00625 00626 UINT16 sb_DSP_dma_in8hs_single( UINT16 _sb_baseport ) 00627 { 00628 return sb_DSP_write(_sb_baseport,0x99); 00629 } 00630 00631 /**********************************************************/ 00632 /* Comando DSP A0h. 00633 Selecciona modo mono. 00634 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00635 version DSP 3.xx 00636 .................... 00637 DSP command A0h. 00638 Selects mono mode. 00639 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00640 DSP version 3.xx */ 00641 00642 UINT16 sb_DSP_mono( UINT16 _sb_baseport ) 00643 { 00644 return sb_DSP_write(_sb_baseport,0xA0); 00645 } 00646 00647 /**********************************************************/ 00648 /* Comando DSP A8h. 00649 Selecciona modo estereo. 00650 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00651 version DSP 3.xx 00652 .................... 00653 DSP command A8h. 00654 Selects stereo mode. 00655 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00656 DSP version 3.xx */ 00657 00658 UINT16 sb_DSP_stereo( UINT16 _sb_baseport ) 00659 { 00660 return sb_DSP_write(_sb_baseport,0xA8); 00661 } 00662 00663 /**********************************************************/ 00664 /* Comando DSP Bxh. 00665 Programa modo AD/DA de 16 bits (muestras de 16 bits, DMA de 16 (o 8) bits. 00666 {input} = FALSE para DA, TRUE para AD. 00667 {auto_init} = FALSE para ciclo unico, TRUE para autoinicializacion. 00668 {fifo} = FALSE para off, TRUE para on. FIFO se reinicializa con cada 00669 nuevo comando (????). 00670 {stereo} = FALSE para mono, TRUE para estereo. 00671 {signed_val} = FALSE para muestras sin signo, TRUE para muestras con signo. 00672 {samples_minus_1} es el numero de muestras menos 1 que deben grabarse o 00673 reproducirse en modo de ciclo unico. En modo de autoinicializacion indica 00674 el numero de muestras menos 1 cada cuanto se tiene que generar la 00675 interrupcion. 00676 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00677 version DSP 4.xx 00678 .................... 00679 DSP command set Bxh. 00680 Programs 16 bits AD/DA (16 bit samples, DMA channel may be 16 or 8 bit). 00681 {input} = FALSE for DA (play), TRUE for AD (rec) conversion. 00682 {auto_init} = FALSE for single cicle, TRUE for autoinit. 00683 {fifo} = FALSE for fifo-off, TRUE for fifo-on. The FIFO is re-initialized 00684 with each command. 00685 {stereo} = FALSE for mono, TRUE for stereo. 00686 {signed_val} = FALSE for unsigned int samples, TRUE for signed int samples. 00687 {samples_minus_1} is the number of samples-1 to play/record on single cicle 00688 mode. On autoinit mode, it is the block length-1 (SB will raise an 00689 interrupt signal whenever it processes a full block). 00690 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00691 DSP version 4.xx */ 00692 00693 UINT16 sb_DSP_16( UINT16 _sb_baseport, BOOL input, BOOL auto_init, 00694 BOOL fifo, BOOL stereo, BOOL signed_val, UINT16 samples_minus_1 ) 00695 { 00696 if (sb_DSP_write(_sb_baseport,0xB0 | (input?0x08:0x00) | (auto_init?0x04:0x00) | 00697 (fifo?0x02:0x00)) == DSP_ERROR) 00698 return DSP_ERROR; 00699 00700 if (sb_DSP_write(_sb_baseport,(stereo?0x20:0x00) | (signed_val?0x10:0x00)) == 00701 DSP_ERROR) 00702 return DSP_ERROR; 00703 00704 if (sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1)) == DSP_ERROR) 00705 return DSP_ERROR; 00706 00707 return sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1 >> 8)); 00708 } 00709 00710 /**********************************************************/ 00711 /* Comando DSP Cxh. 00712 Programa modo AD/DA de 8 bits (muestras de 8 bits, DMA de 8 bits. 00713 {input} = FALSE para DA, TRUE para AD. 00714 {auto_init} = FALSE para ciclo unico, TRUE para autoinicializacion. 00715 {fifo} = FALSE para off, TRUE para on. FIFO se reinicializa con cada 00716 nuevo comando (????). 00717 {stereo} = FALSE para mono, TRUE para estereo. 00718 {signed_val} = FALSE para muestras sin signo, TRUE para muestras con signo. 00719 {samples_minus_1} es el numero de muestras menos 1 que deben grabarse o 00720 reproducirse en modo de ciclo unico. En modo de autoinicializacion indica 00721 el numero de muestras menos 1 cada cuanto se tiene que generar la 00722 interrupcion. 00723 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00724 version DSP 4.xx 00725 .................... 00726 DSP command set Cxh. 00727 Programs 8 bits AD/DA (16 bit samples, DMA 8 bits). 00728 {input} = FALSE for DA (play), TRUE for AD (rec) conversion. 00729 {auto_init} = FALSE for single cicle, TRUE for autoinit. 00730 {fifo} = FALSE for fifo-off, TRUE for fifo-on. The FIFO is re-initialized 00731 with each command. 00732 {stereo} = FALSE for mono, TRUE for stereo. 00733 {signed_val} = FALSE for unsigned char samples, TRUE for signed char samples. 00734 {samples_minus_1} is the number of samples-1 to play/record on single cicle 00735 mode. On autoinit mode, it is the block length-1 (SB will raise an 00736 interrupt signal whenever it processes a full block). 00737 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00738 DSP version 4.xx */ 00739 00740 UINT16 sb_DSP_8( UINT16 _sb_baseport, BOOL input, BOOL auto_init, 00741 BOOL fifo, BOOL stereo, BOOL signed_val, UINT16 samples_minus_1 ) 00742 { 00743 if (sb_DSP_write(_sb_baseport,0xC0 | (input?0x08:0x00) | (auto_init?0x04:0x00) | 00744 (fifo?0x02:0x00)) == DSP_ERROR) 00745 return DSP_ERROR; 00746 00747 if (sb_DSP_write(_sb_baseport,(stereo?0x20:0x00) | (signed_val?0x10:0x00)) == 00748 DSP_ERROR) 00749 return DSP_ERROR; 00750 00751 if (sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1)) == DSP_ERROR) 00752 return DSP_ERROR; 00753 00754 return sb_DSP_write(_sb_baseport,(UINT8)(samples_minus_1 >> 8)); 00755 } 00756 00757 /**********************************************************/ 00758 /* Comando DSP D0h. 00759 Pausa en AD/DA de 8 bits. 00760 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00761 version DSP 1.xx, 2.00, 2.01+, 3.xx, 4.xx 00762 .................... 00763 DSP command D0h. 00764 Pause 8 bits AD/DA conversion. 00765 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00766 DSP version 1.xx, 2.00, 2.01+, 3.xx, 4.xx */ 00767 00768 UINT16 sb_DSP_8_pause( UINT16 _sb_baseport ) 00769 { 00770 return sb_DSP_write(_sb_baseport,0xD0); 00771 } 00772 00773 /**********************************************************/ 00774 /* Comando DSP D1h. 00775 Enciende speaker (necesario para escuchar D/A en DSPs anteriores 00776 a 4.xx). 00777 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00778 version DSP 1.xx, 2.00, 2.01+, 3.xx, 4.xx 00779 .................... 00780 DSP command D1h. 00781 Switch on SB speaker. You must send this command to enable D/A 00782 conversion on DSPs previous to 4.xx. 00783 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00784 DSP version 1.xx, 2.00, 2.01+, 3.xx, 4.xx */ 00785 00786 UINT16 sb_DSP_speaker_on( UINT16 _sb_baseport ) 00787 { 00788 return sb_DSP_write(_sb_baseport,0xD1); 00789 } 00790 00791 /**********************************************************/ 00792 /* Comando DSP D3h. 00793 Apaga speaker. 00794 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00795 version DSP 1.xx, 2.00, 2.01+, 3.xx, 4.xx 00796 .................... 00797 DSP command D3h. 00798 Switch off SB speaker. 00799 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00800 DSP version 1.xx, 2.00, 2.01+, 3.xx, 4.xx */ 00801 00802 UINT16 sb_DSP_speaker_off( UINT16 _sb_baseport ) 00803 { 00804 return sb_DSP_write(_sb_baseport,0xD3); 00805 } 00806 00807 /**********************************************************/ 00808 /* Comando DSP D4h. 00809 Continua AD/DA de 8 bits, despues de poner en modo pausa con 00810 comando D0h. 00811 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00812 version DSP 1.xx, 2.00, 2.01+, 3.xx, 4.xx 00813 .................... 00814 DSP command D4h. 00815 Continue 8 bit AD/DA conversion if we have previously sent 00816 the pause command (D0h) to the DSP. 00817 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00818 DSP version 1.xx, 2.00, 2.01+, 3.xx, 4.xx */ 00819 00820 UINT16 sb_DSP_8_continue( UINT16 _sb_baseport ) 00821 { 00822 return sb_DSP_write(_sb_baseport,0xD4); 00823 } 00824 00825 /**********************************************************/ 00826 /* Comando DSP D5h. 00827 Pausa en AD/DA de 16 bits. 00828 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00829 version DSP 4.xx 00830 .................... 00831 DSP command D5h. 00832 Pause 16 bits AD/DA conversion. 00833 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00834 DSP version 4.xx */ 00835 00836 UINT16 sb_DSP_16_pause( UINT16 _sb_baseport ) 00837 { 00838 return sb_DSP_write(_sb_baseport,0xD5); 00839 } 00840 00841 /**********************************************************/ 00842 /* Comando DSP D6h. 00843 Continua AD/DA de 16 bits, despues de poner en modo pausa con 00844 comando D5h. 00845 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00846 version DSP 4.xx 00847 .................... 00848 DSP command D6h. 00849 Continue 16 bit AD/DA conversion if we have previously sent 00850 the pause command (D5h) to the DSP. 00851 {returns} DSP_ERROR (0xFFFF) if error, or 0 if succeeds. 00852 DSP version 4.xx */ 00853 00854 UINT16 sb_DSP_16_continue( UINT16 _sb_baseport ) 00855 { 00856 return sb_DSP_write(_sb_baseport,0xD6); 00857 } 00858 00859 /**********************************************************/ 00860 /* Comando DSP D8h. 00861 {devuelve} el estado del speaker. 0 para off, 1 para on. 00862 {devuelve} DSP_ERROR (0xFFFF) si error. 00863 version DSP 2.00, 2.01+, 3.xx, 4.xx 00864 .................... 00865 DSP command D8h. 00866 {returns} the SB internal speaker status. 0=off, 1=on. 00867 {returns} DSP_ERROR (0xFFFF) on error. 00868 DSP version 2.00, 2.01+, 3.xx, 4.xx */ 00869 00870 UINT16 sb_DSP_speaker( UINT16 _sb_baseport ) 00871 { 00872 UINT16 spk; 00873 00874 if (sb_DSP_write(_sb_baseport,0xD8)) 00875 return DSP_ERROR; 00876 00877 00878 spk = sb_DSP_read(_sb_baseport); 00879 if (spk == DSP_ERROR) 00880 return DSP_ERROR; 00881 else if (spk == 0xFF) 00882 return 1; 00883 00884 return 0; 00885 } 00886 00887 /**********************************************************/ 00888 /* Comando DSP D9h. 00889 Al final de la transferencia en curso, se abandono el modo de 00890 autoinicializacion AD/DA de 16 bits, y se detiene el proceso. 00891 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00892 version DSP 4.xx 00893 .................... 00894 Programs the DSP so that when the current DMA transfer ends, 00895 the cards exits the autoinitialize mode, stopping the AD/DA 16 bit 00896 conversion. 00897 The function {returns} 0 if succeeds, or DSP_ERROR (0xFFFF) on 00898 error. 00899 DSP version 4.xx */ 00900 00901 00902 UINT16 sb_DSP_16_exit( UINT16 _sb_baseport ) 00903 { 00904 return sb_DSP_write(_sb_baseport,0xD9); 00905 } 00906 00907 /**********************************************************/ 00908 /* Comando DSP DAh. 00909 Al final de la transferencia en curso, se abandona el modo de 00910 autoinicializacion AD/DA de 8 bits, y se detiene el proceso. 00911 {devuelve} DSP_ERROR (0xFFFF) si error, o 0 si tiene exito. 00912 version DSP 4.xx 00913 .................... 00914 DSP command DAh 00915 Programs the DSP so that when the current DMA transfer ends, 00916 the cards exits the autoinitialize mode, stopping the AD/DA 8 bit 00917 conversion. 00918 The function {returns} 0 if succeeds, or DSP_ERROR (0xFFFF) on 00919 error. 00920 DSP version 4.xx */ 00921 00922 UINT16 sb_DSP_8_exit( UINT16 _sb_baseport ) 00923 { 00924 return sb_DSP_write(_sb_baseport,0xDA); 00925 } 00926 00927 /**********************************************************/ 00928 /* Comando DSP E1h. 00929 {devuelve} la version del DSP, o 0 en caso de error. 00930 version DSP >= 1.0 00931 .................... 00932 DSP command E1h. 00933 {returns} the DSP version, or 0 on error. 00934 DSP version >= 1.0 */ 00935 00936 UINT16 sb_DSP_version( UINT16 _sb_baseport ) 00937 { 00938 UINT16 major, minor; 00939 00940 if (sb_DSP_write(_sb_baseport,0xE1) == DSP_ERROR) 00941 return 0x0000; 00942 00943 major = sb_DSP_read(_sb_baseport); 00944 if (major == DSP_ERROR) 00945 return 0x0000; 00946 00947 minor = sb_DSP_read(_sb_baseport); 00948 if (minor == DSP_ERROR) 00949 return 0x0000; 00950 00951 return (major << 8) | minor; 00952 } 00953 00954 /**********************************************************/ 00955