00001 #ifndef __MK_DSPTransfer_H___ 00002 #define __MK_DSPTransfer_H___ 00003 /* DSPTransfer.h - Functions in libdsp_s.a having to do with data transfer. 00004 * Copyright 1988-1992, NeXT Inc. All rights reserved. 00005 * Author: Julius O. Smith III 00006 */ 00007 00008 #if 0 00009 00010 TERMINOLOGY 00011 00012 A "load" is an immediate transfer of a DSPLoadSpec struct into DSP memory. 00013 A load can occur any time after DSPBoot() or DSP{AP,MK,}Init(). 00014 00015 A "write" is an immediate transfer into DSP memory, 00016 normally used to download user data to the DSP. 00017 00018 A "read" is the inverse of a "write". The transfer is immediate, 00019 without regard for DSP time, if any. 00020 00021 A "get" is the same as a "read", except that the return value of the 00022 function contains the desired datum rather than an error code. 00023 00024 A "vector" is a contiguous array of words. A one-dimensional 00025 (singly subscripted) C array is an example of a vector. 00026 00027 An "array" is a not-necessarily-contiguous sequence of words. 00028 An array is specified by a vector plus a "skip factor". 00029 00030 A "skip factor" is the number of array elements to advance in an 00031 array transfer. An array with a skip factor of 1 is equivalent to 00032 a vector. A skip factor of 2 means take every other element when 00033 reading from the DSP and write every other element when writing to 00034 the DSP. A skip factor of 3 means skip 2 elements between each 00035 read or write, and so on. 00036 00037 ---------------------------------------------------------------------- 00038 00039 The following terms pertain primarily to the Music Kit DSP monitor: 00040 00041 A "send" is a timed transfer into DSP memory. Functions which do 00042 "sends" have prefix "DSPMKSend..." or have the form "DSPMK...Timed()". 00043 00044 A "ret{rieve}" is the inverse of a "send". 00045 00046 A "tick" is DSPMK_I_NTICK samples of digital audio produced by one 00047 iteration of the "orchestra loop" in the DSP. 00048 00049 An "immediate send" is a send in which the time stamp is 0. The global 00050 variable DSPTimeStamp0 exists for specifying a zero time stamp. It 00051 results in a tick-synchronized write, i.e., occurring at end of 00052 current tick in the DSP. 00053 00054 An orchestra must be running on the chip to do either type of send. 00055 Time-stamped DSP directives are always used in the context of the 00056 Music Kit orchestra. 00057 00058 If the time stamp pointer is null (DSPMK_UNTIMED), then a send reduces 00059 to a write. 00060 00061 A "BLT" (BLock Transfer) is a move within DSP memory. 00062 A "BLTB" is a Backwards move within DSP memory. 00063 00064 A "fill" specifies one value to use in filling DSP memory. 00065 00066 #endif 00067 00068 00069 /****************** READING/WRITING HOST-INTERFACE REGISTERS *****************/ 00070 00071 #include "MKDSPDefines.h" 00072 00073 MKDSP_API int DSPReadRegs(unsigned int *regsP); 00074 /* 00075 * Read DSP Interrupt Control Register (ICR), 00076 * Command Vector Register (CVR), 00077 * Interrupt Status Register (ISR), and 00078 * Interrupt Vector Register (IVR), 00079 * in that order, concatenated to form 00080 * a single 32-bit word. 00081 */ 00082 00083 MKDSP_API unsigned int DSPGetRegs(void); 00084 /* 00085 * Same as DSPReadRegs() but returns regs as function value. 00086 */ 00087 00088 00089 MKDSP_API int DSPWriteRegs( 00090 int mask, /* bit mask in (ICR,CVR,ISR,IVR) longword */ 00091 int value); /* bit values in (ICR,CVR,ISR,IVR) longword */ 00092 /* 00093 * Set DSP host-interface bits to given value. 00094 * Returns 0 for success, nonzero on error. 00095 * Example: 00096 * DSPWriteRegs(DSP_ICR_HF0_REGS_MASK,DSP_ICR_HF0_REGS_MASK), 00097 * sets host flag 0 to 1 and 00098 * DSPWriteRegs(DSP_ICR_HF0_REGS_MASK,0)); 00099 * clears it. 00100 */ 00101 00102 00103 MKDSP_API int DSPReadICR(int *icrP); 00104 /* 00105 * Read DSP Interrupt Control Register (ICR). 00106 * value returned in *icrP is 8 bits, right justified. 00107 */ 00108 00109 00110 MKDSP_API int DSPGetICR(void); 00111 /* 00112 * Return ICR register of the DSP host interface. 00113 */ 00114 00115 00116 MKDSP_API int DSPReadCVR(int *cvrP); 00117 /* 00118 * Read DSP Command Vector Register (CVR). 00119 * value returned in *cvrP is 8 bits, right justified. 00120 */ 00121 00122 00123 MKDSP_API int DSPGetCVR(void); 00124 /* 00125 * Return CVR register of the DSP host interface. 00126 */ 00127 00128 00129 MKDSP_API int DSPHostCommand(int cmd); 00130 /* 00131 * Issue DSP "host command". The low-order 5 bits of cmd are sent. 00132 * There are 32 possible host commands, with 18 predefined by Motorola. 00133 * Others are used by the DSP driver for DMA control. See 00134 * <sound/sounddriver.h> for their definitions. 00135 */ 00136 00137 00138 MKDSP_API int DSPReadISR(int *isrP); 00139 /* 00140 * Read DSP Interrupt Status Register (ISR). 00141 * value returned in *isrP is 8 bits, right justified. 00142 */ 00143 00144 00145 MKDSP_API int DSPGetISR(void); 00146 /* 00147 * Return ISR register of the DSP host interface. 00148 */ 00149 00150 00151 MKDSP_API int DSPGetRX(void); 00152 /* 00153 * Return RX register of the DSP host interface. 00154 * Equivalent to "DSPReadRX(&tmp); return tmp;". 00155 */ 00156 00157 MKDSP_API int DSPReadDataAndToss(int n); 00158 /* 00159 * Read n ints from the RX register of the DSP host interface 00160 * and toss them into the bit bucket. Faster than a real read 00161 * for pulling words out of the DSP. 00162 */ 00163 00164 MKDSP_API int DSPReadDataArrayMode(void *data, int nwords, int mode); 00165 /* 00166 * Read nwords words from DSP Receive Byte Registers (RX) in "DMA mode" mode. 00167 * The mode is DSP_MODE<n> where <n> = 8,16,24,32, (using the defines in 00168 * <sound/sounddriver.h>) and the modes are described under the function 00169 * DSPReadArraySkipMode(). 00170 * RXDF must be true for each word before it is read. 00171 * Note that it is an "error" for RXDF not to come true. 00172 * Call DSPAwaitData(msTimeLimit) before calling 00173 * DSPReadRX() in order to await RXDF indefinitely. 00174 * The default time-out used here may change in the future, and it is 00175 * currently infinity. 00176 * This function is for simple non-DMA data reads from the DSP. 00177 * The only protocol used with the DSP is that HF1 is set during the read. 00178 */ 00179 00180 00181 MKDSP_API int DSPReadMessageArrayMode(void *data, int nwords, int mode); 00182 /* 00183 * Like DSPReadDataArrayMode() except for DSP messages. 00184 * Only useable in "host message protocol" mode. 00185 * Return value is 0 for success, nonzero if an element could not be read 00186 * after trying for DSPDefaultTimeLimit seconds. 00187 * If the read could not finish, the number of elements successfully 00188 * read + 1 is returned. 00189 * The mode specifies the data mode as in DSPReadDataArrayMode(). 00190 */ 00191 00192 00193 MKDSP_API int DSPReadRXArrayMode(void *data, int nwords, int mode); 00194 /* 00195 * Equivalent to 00196 * 00197 * if (DSPHostMsgIsEnabled()) 00198 * return DSPReadMessageArrayMode(); 00199 * else 00200 * return DSPReadDataArrayMode(); 00201 */ 00202 00203 00204 MKDSP_API int DSPAwaitRX(int msTimeLimit); 00205 /* 00206 * Equivalent to 00207 * 00208 * if (DSPHostMsgIsEnabled()) 00209 * return DSPAwaitMessages(msTimeLimit); 00210 * else 00211 * return DSPAwaitData(msTimeLimit); 00212 */ 00213 00214 00215 MKDSP_API int DSPReadRXArray(DSPFix24 *data, int nwords); 00216 /* 00217 * Equivalent to DSPReadRXArrayMode(data,nwords,DSP_MODE32); 00218 * Each value is returned as 24 bits, right justified in 32. 00219 */ 00220 00221 00222 MKDSP_API int DSPReadRX(DSPFix24 *wordp); 00223 /* 00224 * Equivalent to DSPReadRXArrayMode(data,1,DSP_MODE32); 00225 * Value returned in *wordp is 24 bits, right justified. 00226 * after waiting DSPDefaultTimeLimit. 00227 */ 00228 00229 00230 MKDSP_API int DSPWriteTX(DSPFix24 word); 00231 /* 00232 * Write word into DSP transmit byte registers. 00233 * Low-order 24 bits are written from word. 00234 */ 00235 00236 00237 MKDSP_API int DSPWriteTXArray( 00238 DSPFix24 *data, 00239 int nwords); 00240 /* 00241 * Feed array to DSP transmit register. 00242 */ 00243 00244 00245 MKDSP_API int DSPWriteTXArrayB( 00246 DSPFix24 *data, 00247 int nwords); 00248 /* 00249 * Feed array *backwards* to DSP TX register 00250 */ 00251 00252 00253 /***************** READ/WRITE ARRAY FROM/TO DSP HOST INTERFACE ***************/ 00254 00255 /* For DMA array transfers to/from DSP */ 00256 00257 MKDSP_API int DSPWriteArraySkipMode( 00258 void *data, /* array to send to DSP (any type ok) */ 00259 DSPMemorySpace memorySpace, /* /LocalDeveloper/Headers/dsp/dsp_structs.h */ 00260 int startAddress, /* within DSP memory */ 00261 int skipFactor, /* 1 means normal contiguous transfer */ 00262 int wordCount, /* from DSP perspective */ 00263 int mode); /* from <nextdev/dspvar.h> */ 00264 /* 00265 * Send an array of words to the DSP. 00266 * The mode is one of (cf. dspvar.h): 00267 * 00268 * DSP_MODE8 00269 * DSP_MODE16 00270 * DSP_MODE24 00271 * DSP_MODE32 00272 * 00273 * Mode DSP_MODE8 maps successive bytes from the source byte array to 00274 * successive words in the DSP. Each byte is right justified in the 00275 * 24-bit DSP word. The upper two bytes of each DSP word will contain 00276 * whatever was last written to the TXH and TXM registers in the DSP 00277 * host interface. Therefore, if you want leading zeros, for example, 00278 * you could write the first byte using DSPWriteValue(value,space,addr). 00279 * 00280 * Mode DSP_MODE16 maps successive byte pairs from the source byte array to 00281 * successive words in the DSP. Each 16-bit word from the source is right 00282 * justified in the 24-bit DSP word. The upper byte of each DSP word 00283 * will contain whatever was last written to the TXH register 00284 * in the DSP host interface. 00285 * 00286 * Mode DSP_MODE24 maps successive byte trios from the source byte array to 00287 * successive words in the DSP. Each 24-bit word from the source occupies 00288 * a full 24-bit DSP word. 00289 * 00290 * Mode DSP_MODE32 maps the least significant three bytes from each four-byte 00291 * word in the source array to successive words in the DSP. Each 32-bit word 00292 * from the source specifies a full 24-bit DSP word. 00293 * 00294 * The skip factor specifies the increment for the DSP address register 00295 * used in the DMA transfer. A skip factor of 1 means write successive 00296 * words contiguously in DSP memory. A skip factor of 2 means skip every 00297 * other DSP memory word, etc. 00298 * 00299 * A DMA transfer is performed if it will be sufficiently large. 00300 * DMA transfers must be quad aligned (16-bytes = 1 quad) and a multiple of 16 bytes 00301 * in length. A DMA cannot cross a page boundary (currently 8192 bytes). 00302 * This routine will break up your array into 00303 * separate transfers, if necessary. For best performance, use arrays 00304 * that begin on a page boundary (e.g. "mem = malloc(byteCount+vm_page_size); 00305 * array = mem & (~(vm_page_size-1));"). 00306 * 00307 * This routing calls snddriver_dsp_dma_write() to carry out the DMA transfers. 00308 * You can save a little overhead by using vm_allocate() to prepare your data 00309 * buffer and calling snddriver_dsp_dma_write() directly. In that case, you 00310 * will need to set and clear the "complex DMA" protocol bit yourself (see 00311 * DSPSetComplexDMAModeBit(int bit)), and you will have to prepare the DSP 00312 * for the transfer yourself. (The Music Kit and array processing monitors 00313 * support a transfer-preparation call that libdsp uses. The snddriver functions 00314 * assume a minimum of DSP-side protocol, so transfer preparation is up to the 00315 * DSP programmer.) Note that vm_allocate() always allocates a multiple of whole 00316 * virtual-memory pages, and the starting address is always page aligned. 00317 * Such buffers are most effficient for DMA transfer. If you pass such a buffer 00318 * to libdsp, it will look over it quite a bit, but otherwise realize the benefits. 00319 */ 00320 00321 00322 MKDSP_API int DSPReadNewArraySkipMode( 00323 void **data, /* array to fill from DSP */ 00324 DSPMemorySpace memorySpace, /* /LocalDeveloper/Headers/dsp/dsp_structs.h */ 00325 int startAddress, /* within DSP memory */ 00326 int skipFactor, /* 1 means normal contiguous transfer */ 00327 int wordCount, /* from DSP perspective */ 00328 int mode); /* from <nextdev/dspvar.h> */ 00329 /* 00330 * Receive an array of bytes from the DSP. 00331 * Operation is analogous to that of DSPWriteArraySkipMode() 00332 * except that the array is allocated by the function. Its size 00333 * will be the number of bytes returned rounded up to the next 00334 * multiple of 32. It should be freed using vm_deallocate(). 00335 * 00336 * Note: In order to relieve pressure on the host side, 00337 * the DSP blocks from the time the host is interrupted 00338 * to say that reading can begin and the time the host tells 00339 * the DSP that the host interface has been initialized in DMA 00340 * mode. Therefore, this routine should not be used to read DSP 00341 * memory while an orchestra is running. 00342 */ 00343 00344 00345 MKDSP_API int DSPReadArraySkipMode( 00346 void *data, /* array to fill from DSP */ 00347 DSPMemorySpace memorySpace, 00348 int startAddress, /* within DSP memory */ 00349 int skipFactor, /* 1 means normal contiguous transfer */ 00350 int wordCount, /* from DSP perspective */ 00351 int mode); /* DMA mode from <nextdev/dspvar.h> */ 00352 /* 00353 * Same as DSPReadNewArraySkipMode() except that data from the 00354 * DSP is copied into the data array provided in the argument. 00355 */ 00356 00357 /****************************************************************************/ 00358 00359 MKDSP_API int DSPWriteValue(int value, DSPMemorySpace space, int addr); 00360 /* 00361 * Write the low-order 24 bits of value to space:addr in DSP memory. 00362 * The space argument is one of 00363 * (cf. "/LocalDeveloper/Headers/dsp/dsp_structs.h"): 00364 * DSP_MS_X 00365 * DSP_MS_Y 00366 * DSP_MS_P 00367 */ 00368 00369 00370 MKDSP_API int DSPWriteLong(DSPFix48 *aFix48Val, int addr); 00371 /* 00372 * Write a DSP double-precision value to l:addr in DSP memory. 00373 * Equivalent to two calls to DSPWriteValue() for the high-order 00374 * and low-order words. 00375 */ 00376 00377 00378 MKDSP_API int DSPWriteFix24Array( 00379 DSPFix24 *data, /* array to write to DSP */ 00380 DSPMemorySpace memorySpace, 00381 DSPAddress startAddress, /* within DSP memory */ 00382 int skipFactor, /* 1 means normal contiguous transfer */ 00383 int wordCount); /* from DSP perspective */ 00384 00385 /* 00386 * Write an array of 24-bit words, right-justified in 32 bits, to the DSP, 00387 * writing three bytes to each successive DSP word. Uses 32-bit DMA mode. 00388 * The rightmost (least-significant) three bytes of each 32-bit source 00389 * word go to the corresponding DSP word. The most significant byte of 00390 * each source word is ignored. 00391 * 00392 * The skip factor specifies the increment for the DSP address register 00393 * used in the DMA transfer. A skip factor of 1 means write successive 00394 * words contiguously in DSP memory. A skip factor of 2 means skip every 00395 * other DSP memory word, etc. 00396 * 00397 * The write is done using 32-bit DMA mode if wordCount is 00398 * DSP_MIN_DMA_WRITE_SIZE or greater, programmed I/O otherwise. Note 00399 * that the DMA transfer is inherently left-justified, while programmed I/O 00400 * is inherently right justified. For large array transfers, it is more 00401 * efficient to work with left-justified data, as provided by 00402 * DSPWriteFix24ArrayLJ(). 00403 * 00404 * This function is also used to transfer unpacked byte arrays or 00405 * unpacked sound arrays to the DSP. In these cases the data words 00406 * are right-justified in the 32-bit words of the source array. 00407 * 00408 * The memorySpace is one of (see dsp_structs.h): 00409 * DSP_MS_X 00410 * DSP_MS_Y 00411 * DSP_MS_P 00412 */ 00413 00414 00415 MKDSP_API int DSPWriteFix24ArrayLJ( 00416 DSPFix24 *data, /* array to write to DSP */ 00417 DSPMemorySpace memorySpace, 00418 DSPAddress startAddress, /* within DSP memory */ 00419 int skipFactor, /* 1 means normal contiguous transfer */ 00420 int wordCount); /* from DSP perspective */ 00421 /* 00422 * Same as DSPWriteFix24Array except that the data array is assumed to be 00423 * left-justified in 32 bits. 00424 */ 00425 00426 00427 MKDSP_API int DSPWriteIntArray( 00428 int *intArray, 00429 DSPMemorySpace memorySpace, 00430 DSPAddress startAddress, 00431 int skipFactor, 00432 int wordCount); 00433 /* 00434 * Same as DSPWriteFix24Array. The low-order 24 bits of each int are 00435 * transferred into each DSP word. 00436 */ 00437 00438 00439 MKDSP_API int DSPWritePackedArray( 00440 unsigned char *data, /* Data to write to DSP */ 00441 DSPMemorySpace memorySpace, /* DSP memory space */ 00442 DSPAddress startAddress, /* DSP start address */ 00443 int skipFactor, /* DSP index increment per DSP word written */ 00444 int wordCount); /* DSP words = byte count / 3 */ 00445 00446 /* 00447 * Write a byte array to the DSP, writing three bytes to 00448 * each successive DSP word. Uses 24-bit DMA mode. 00449 * This is the most compact form of transfer to the DSP. 00450 */ 00451 00452 00453 MKDSP_API int DSPEnableDmaReadWrite(int enable_dma_reads, int enable_dma_writes); 00454 /* 00455 * Enable or disable use of DMA in 16-bit and 8-bit mode transfers. 00456 * The default is disabled. To enable DMA in both directions, say 00457 * 00458 * DSPEnableDmaReadWrite(1,1); 00459 * 00460 * DMA is disabled by default because it cannot currently be mixed with 00461 * programmed transfers. Attempting to do so may cause a driver panic. 00462 */ 00463 00464 00465 MKDSP_API int DSPWriteShortArray( 00466 short int *data, /* Packed short data to write to DSP */ 00467 DSPMemorySpace memorySpace, /* DSP memory space */ 00468 DSPAddress startAddress, /* DSP start address */ 00469 int skipFactor, /* DSP index increment per short written */ 00470 int wordCount); /* DSP word count = byte count / 2 */ 00471 00472 /* 00473 * Write a packed array of 16-bit words to the DSP (typically sound data). 00474 * Uses 16-bit DMA mode if possible and if enabled. Each 32-bit word in the 00475 * source array provides two successive 16-bit samples in the DSP. 00476 * In the DSP, each 16-bit word is received right-justified in 24 bits, 00477 * with no sign extension. For best results, the data array should be 00478 * allocated using vm_allocate() (to obtain page alignment), and the length 00479 * of the transfer should be a multiple of 4096 bytes (the current DMA buffer 00480 * size within libdsp). Otherwise, if the buffer is poorly aligned and of 00481 * an odd length, the first and last block transfers will be carried out using 00482 * programmed I/O. Internally, the function snddriver_dsp_dma_write() is used 00483 * to perform the DMA transfers. See the release notes DSPNotes.rtf for more 00484 * information about DMA usage. 00485 */ 00486 00487 00488 MKDSP_API int DSPWriteByteArray( 00489 unsigned char *data, /* Data to write to DSP */ 00490 DSPMemorySpace memorySpace, /* DSP memory space */ 00491 DSPAddress startAddress, /* DSP start address */ 00492 int skipFactor, /* DSP index increment per byte transferred */ 00493 int byteCount); /* Total number of bytes to transfer */ 00494 00495 /* 00496 * Write a packed array of 8-bit words to the DSP (typically microphone data). 00497 * Uses 8-bit DMA mode if possible and if enabled. Each 32-bit word in the 00498 * source array provides four successive 8-bit samples to the DSP, 00499 * right-justified within 24 bits without sign extension. 00500 * In the DSP, each byte is received right-justified in 24 bits. 00501 * See DSPWriteShortArray() for alignment and length considerations. 00502 * See the release notes DSPNotes.rtf for more information about DMA usage. 00503 */ 00504 00505 00506 MKDSP_API int DSPWriteFloatArray( 00507 float *floatArray, 00508 DSPMemorySpace memorySpace, 00509 DSPAddress startAddress, 00510 int skipFactor, 00511 int wordCount); 00512 /* 00513 * Write a vector of floating-point numbers to a DSP array. 00514 * Equivalent to DSPFloatToFix24Array() followed by DSPWriteFix24Array(). 00515 */ 00516 00517 00518 MKDSP_API int DSPWriteDoubleArray( 00519 double *doubleArray, 00520 DSPMemorySpace memorySpace, 00521 DSPAddress startAddress, 00522 int skipFactor, 00523 int wordCount); 00524 /* 00525 * Write a vector of double-precision floating-point numbers to a DSP array. 00526 * Equivalent to DSPDoubleToFix24Array() followed by DSPWriteFix24Array(). 00527 */ 00528 00529 MKDSP_API int DSPWriteSCI(unsigned char value, DSPSCITXReg reg); 00530 /* Write a byte to the specified SCI register. SCI must already be 00531 * set up with DSPSetupSerialPort(DSPSerialPortParameters *p). 00532 */ 00533 00534 MKDSP_API int DSPDataRecordLoad(DSPDataRecord *dr); 00535 /* 00536 * Load data record (as filled from assembler's _DATA record) into DSP. 00537 * See "/LocalDeveloper/Headers/dsp/dsp_structs.h" for the struct format. 00538 */ 00539 00540 00541 /* Music Kit versions: timed data transfers to DSP */ 00542 00543 MKDSP_API int DSPMKSendValue(int value, DSPMemorySpace space, int addr); 00544 /* 00545 * Equivalent to DSPWriteValue() except synchronized to a tick boundary 00546 * (i.e., executed at the top of the orchestra loop). 00547 * Equivalent to DSPMKSendValueTimed(DSPMKTimeStamp0,value,space,addr). 00548 */ 00549 00550 00551 MKDSP_API int DSPMKSendValueTimed(DSPFix48 *aTimeStampP, 00552 int value, 00553 DSPMemorySpace space, 00554 int addr); 00555 /* 00556 * Set a DSP memory location to a particular value at a particular time. 00557 */ 00558 00559 00560 MKDSP_API int DSPMKSendLong(DSPFix48 *aFix48Val, int addr); 00561 /* 00562 * etc. 00563 */ 00564 00565 00566 MKDSP_API int DSPMKSendLongTimed(DSPFix48 *aTimeStampP, 00567 DSPFix48 *aFix48Val, 00568 int addr); 00569 00570 00571 MKDSP_API int DSPMKSendArraySkipModeTimed( 00572 DSPFix48 *aTimeStampP, 00573 void *data, /* Interpretation depends on mode arg */ 00574 DSPMemorySpace space, 00575 DSPAddress address, 00576 int skipFactor, 00577 int count, /* DSP wordcount */ 00578 int mode); /* from <nextdev/dspvar.h> */ 00579 /* 00580 * Send an array of data to the DSP at a particular time. 00581 * The array is broken down into chunks which will fit into the Music Kit 00582 * DSP monitor's Host Message Stack, and as many timed messages as necessary 00583 * are sent to transfer the array. 00584 * 00585 * See DSPObject.h, function DSPWriteArraySkipMode() for a description of 00586 * the various data modes and how they work. 00587 * 00588 * When this function is called, timed messages are flushed, and the 00589 * array transfers are not optimized. That is, there is no command 00590 * stream optimization for timed array transfers as there is for 00591 * other timed host messages. This means that multiple timed array transfers 00592 * going out at the same time will be transferred separately rather than being 00593 * batched. If the arrays are so small and numerous that this optimization 00594 * seems warranted, use DSPMKSendValueTimed() instead. 00595 * 00596 * This function and its derivatives are intended for timed one-shot transfers 00597 * such as downloading oscillator wavetables. DMA is not used, and the entire 00598 * array is held in the Timed Message Queue within the DSP until the 00599 * transfer time according to the DSP sample clock arrives. 00600 * For continuous data transfers into a DSP orchestra, use the "read data" 00601 * feature in the Music Kit. The read-data stream can be stopped and 00602 * started at particular times if desired. 00603 */ 00604 00605 00606 MKDSP_API int DSPMKSendArraySkipTimed(DSPFix48 *aTimeStampP, 00607 DSPFix24 *data, 00608 DSPMemorySpace space, 00609 DSPAddress address, 00610 int skipFactor, 00611 int count); 00612 /* 00613 * Calls DSPMKSendArraySkipModeTimed() with mode == DSP_MODE32. 00614 */ 00615 00616 00617 MKDSP_API int DSPMKSendArrayTimed(DSPFix48 *aTimeStampP, 00618 DSPFix24 *data, 00619 DSPMemorySpace space, 00620 DSPAddress address, 00621 int count); 00622 /* 00623 * Calls DSPMKSendArraySkipTimed() with skipFactor equal to 1. 00624 */ 00625 00626 00627 MKDSP_API int DSPMKSendArray(DSPFix24 *data, 00628 DSPMemorySpace space, 00629 DSPAddress address, 00630 int count); 00631 /* 00632 * Calls DSPMKSendArrayTimed() with skipFactor == 1 and time stamp == 0. 00633 */ 00634 00635 00636 MKDSP_API int DSPMKSendShortArraySkipTimed(DSPFix48 *aTimeStampP, 00637 short int *data, 00638 DSPMemorySpace space, 00639 DSPAddress address, 00640 int skipFactor, 00641 int count); 00642 /* 00643 * Calls DSPMKSendArraySkipModeTimed() with mode == DSP_MODE16. 00644 * Two successive DSP words get left and right 16 bits of each data word. 00645 * The 16-bit words are received right-justified in each DSP word. 00646 */ 00647 00648 00649 /****************************** DSP MEMORY FILLS *****************************/ 00650 00651 /* 00652 * DSP "memory fills" tell the DSP to rapidly initialize a block of 00653 * the DSP's private static RAM. 00654 */ 00655 00656 MKDSP_API int DSPMemoryFill( 00657 DSPFix24 fillConstant, /* value to use as DSP memory initializer */ 00658 DSPMemorySpace memorySpace, 00659 DSPAddress startAddress, /* first address within DSP memory to fill */ 00660 int wordCount); /* number of DSP words to initialize */ 00661 /* 00662 * Set a block of DSP private RAM to the given fillConstant. 00663 * The memorySpace is one of (see dsp_structs.h): 00664 * 00665 * DSP_MS_X 00666 * DSP_MS_Y 00667 * DSP_MS_P 00668 * 00669 * corresponding to the three memory spaces within the DSP. 00670 * The wordCount is in DSP words. The least-significant 24-bits 00671 * of the fillConstant are copied into wordCount DSP words, beginning 00672 * with location startAddress. 00673 */ 00674 00675 00676 MKDSP_API int DSPMKSendMemoryFill( 00677 DSPFix24 fillConstant, /* value to fill memory with */ 00678 DSPMemorySpace space, /* space of memory fill in DSP */ 00679 DSPAddress address, /* first address of fill in DSP memory */ 00680 int count); /* number of DSP memory words to fill */ 00681 /* 00682 * Fill DSP memory block space:address#count with given fillConstant. 00683 * Synchronized to tick boundary. 00684 */ 00685 00686 00687 MKDSP_API int DSPMKMemoryFillTimed( 00688 DSPFix48 *aTimeStampP, /* time to do memory fill in the DSP */ 00689 DSPFix24 fillConstant, 00690 DSPMemorySpace space, 00691 DSPAddress address, 00692 int count); 00693 /* 00694 * Fill DSP memory block space:address#count with given fillConstant 00695 * at specified time. 00696 */ 00697 00698 00699 MKDSP_API int DSPMKMemoryFillSkipTimed( 00700 DSPFix48 *aTimeStampP, 00701 DSPFix24 fillConstant, 00702 DSPMemorySpace space, 00703 DSPAddress address, 00704 int skip, /* skip factor in DSP memory */ 00705 int count); 00706 /* 00707 * Fill DSP memory block space:address+skip*i, i=0 to count-1 00708 * with given fillConstant at specified time. 00709 */ 00710 00711 00712 MKDSP_API int DSPMemoryClear(DSPMemorySpace memorySpace, 00713 DSPAddress startAddress, 00714 int wordCount); 00715 /* 00716 * Set a block of DSP private RAM to zero. 00717 * Equivalent to DSPMemoryFill(0,memorySpace,startAddress,wordCount); 00718 */ 00719 00720 MKDSP_API int DSPMKSendMemoryClear(DSPMemorySpace space, 00721 DSPAddress address, 00722 int count); 00723 00724 MKDSP_API int DSPMKMemoryClearTimed(DSPFix48 *aTimeStampP, 00725 DSPMemorySpace space, 00726 DSPAddress address, 00727 int count); 00728 00729 /**************************** Poking DSP Symbols ****************************/ 00730 00731 MKDSP_API int DSPPoke(char *name, DSPFix24 value, DSPLoadSpec *dsp); 00732 /* 00733 * Set the value of the DSP symbol with the given name to value (in the DSP). 00734 * 00735 * Equivalent to DSPWriteValue(value,space,address) where space and address 00736 * are obtained via DSPReadSectionSymbolAddres(&space,&address,name, 00737 * DSPGetUserSection(dsp)); 00738 */ 00739 00740 00741 MKDSP_API int DSPPokeFloat(char *name, float value, DSPLoadSpec *dsp); 00742 /* 00743 * Equivalent to DSPPoke(name, DSPFloatToFix24(value), dsp). 00744 */ 00745 00746 00747 /************************** TRANSFERS FROM THE DSP ***************************/ 00748 00749 /* 00750 * These "from the DSP" routines are analogous to the "to DSP" routines 00751 * above. Hence, they are generally not documented when exactly analogous. 00752 */ 00753 00754 00755 MKDSP_API int DSPMKRetValueTimed( 00756 DSPTimeStamp *aTimeStampP, 00757 DSPMemorySpace space, 00758 DSPAddress address, 00759 DSPFix24 *value); 00760 /* 00761 * Send a timed peek. Since we do not know the current time within the 00762 * DSP, we wait forever for the returned value from the DSP. The Music Kit 00763 * orchestra loop must be running, as is the case for any timed message. 00764 */ 00765 00766 00767 MKDSP_API int DSPMKRetValue(DSPMemorySpace space, 00768 DSPAddress address, 00769 DSPFix24 *value); 00770 /* 00771 * Implemented as DSPMKRetValueTimed(&DSPMKTimeStamp0,space,address,value); 00772 * 00773 * A time stamp of zero means "as soon as possible" which is the time of the 00774 * last message currently waiting in the timed message queue. Note: this is 00775 * the result of a bug in time-zero messages. They are supposed to be 00776 * processed at the next tick boundary before any timed messages waiting in 00777 * the queue. To avoid having zero-timed messages stuck behind messages 00778 * timed for the distant future, it is necessary to avoid running far ahead 00779 * of real time (e.g., using "unclocked mode" in the Music Kit). In clocked 00780 * mode, the execution delay should be approximately "delta-T" which is the 00781 * time the Music Kit runs ahead of the DSP's clock. 00782 */ 00783 00784 MKDSP_API int DSPReadValue(DSPMemorySpace space, 00785 DSPAddress address, 00786 DSPFix24 *value); 00787 /* 00788 * Implemented as DSPMKRetValueTimed(DSPMK_UNTIMED,space,address,value); 00789 * 00790 * A null time stamp means "instantly" at interrupt level within the DSP. 00791 * The orchestra loop, if running, will be at an unknown point, and the read 00792 * is not synchronized to a tick boundary. 00793 */ 00794 00795 /* 00796 * The following routines cannot be used with the Music Kit because 00797 * the read mechanism uses the same I/O register in the DSP as does 00798 * sound-out or write date. 00799 */ 00800 00801 DSPFix24 DSPGetValue(DSPMemorySpace space, DSPAddress address); 00802 /* 00803 * Get DSP memory datum at space:address. 00804 * 00805 * Implemented as 00806 * DSPReadArraySkipMode(&datum,space,address,skipFactor,count,DSP_MODE32)) 00807 */ 00808 00809 MKDSP_API int DSPReadFix24Array( 00810 DSPFix24 *data, /* array to fill from DSP */ 00811 DSPMemorySpace memorySpace, 00812 DSPAddress startAddress, /* within DSP memory */ 00813 int skipFactor, /* 1 means normal contiguous transfer */ 00814 int wordCount); /* from DSP perspective */ 00815 /* 00816 * Read an array of 24-bit words, right-justified in 32 bits, to the DSP, 00817 * reading three bytes to each successive DSP word. 00818 * The rightmost (least-significant) three bytes of each 32-bit source 00819 * word go to the corresponding DSP word. The most significant byte of 00820 * each source word is ignored. 00821 * 00822 * The skip factor specifies the increment for the DSP address register 00823 * used in the DMA transfer. A skip factor of 1 means write successive 00824 * words contiguously in DSP memory. A skip factor of 2 means skip every 00825 * other DSP memory word, etc. 00826 * 00827 * The read is done using 32-bit DMA mode if wordCount is 00828 * DSP_MIN_DMA_READ_SIZE or greater, programmed I/O otherwise. Note 00829 * that DMA transfers are inherently left-justified, while programmed I/O is 00830 * inherently right justified. For large array transfers, it is more 00831 * efficient to work with left-justified data, as provided by 00832 * DSPReadFix24ArrayLJ(). 00833 * 00834 * This function is also used to transfer unpacked byte arrays or 00835 * unpacked sound arrays to the DSP. In these cases the data words 00836 * are right-justified in the 32-bit words of the source array. 00837 * 00838 * The memorySpace is one of (see dsp_structs.h): 00839 * DSP_MS_X 00840 * DSP_MS_Y 00841 * DSP_MS_P 00842 * 00843 * Implemented as 00844 * DSPReadArraySkipMode(data,memorySpace,startAddress,skipFactor, 00845 * wordCount,DSP_MODE32); 00846 */ 00847 00848 00849 MKDSP_API int DSPReadFix24ArrayLJ( 00850 DSPFix24 *data, /* array to fill from DSP */ 00851 DSPMemorySpace memorySpace, 00852 DSPAddress startAddress, /* within DSP memory */ 00853 int skipFactor, /* 1 means normal contiguous transfer */ 00854 int wordCount); /* from DSP perspective */ 00855 /* 00856 * Same as DSPReadFix24Array() except that data is returned 00857 * left-justified in 32 bits. 00858 * 00859 * Implemented as 00860 * DSPReadArraySkipMode(data,memorySpace,startAddress,skipFactor, 00861 * wordCount,DSP_MODE32_LEFT_JUSTIFIED); 00862 */ 00863 00864 00865 MKDSP_API int DSPReadIntArray(int *intArray, 00866 DSPMemorySpace memorySpace, 00867 DSPAddress startAddress, 00868 int skipFactor, 00869 int wordCount); 00870 /* 00871 * Same as DSPReadFix24Array() followed by DSPFix24ToIntArray() for 00872 * sign extension. 00873 */ 00874 00875 00876 MKDSP_API int DSPReadPackedArray( 00877 unsigned char *data, /* Data to fill from DSP */ 00878 DSPMemorySpace memorySpace, /* DSP memory space */ 00879 DSPAddress startAddress, /* DSP start address */ 00880 int skipFactor, /* DSP index increment per DSP word read */ 00881 int wordCount); /* DSP words = byte count / 3 */ 00882 00883 MKDSP_API int DSPReadShortArray( 00884 short int *data, /* Packed data to fill from DSP */ 00885 DSPMemorySpace memorySpace, /* DSP memory space */ 00886 DSPAddress startAddress, /* DSP start address */ 00887 int skipFactor, /* DSP index increment per array element */ 00888 int wordCount); /* DSP word count = byte count / 2 */ 00889 00890 MKDSP_API int DSPReadByteArray( 00891 unsigned char *data, /* Data to fill from DSP */ 00892 DSPMemorySpace memorySpace, /* DSP memory space */ 00893 DSPAddress startAddress, /* DSP start address */ 00894 int skipFactor, /* DSP index increment per byte transferred */ 00895 int byteCount); /* Same as DSP word count */ 00896 00897 MKDSP_API int DSPReadFloatArray(float *floatArray, 00898 DSPMemorySpace memorySpace, 00899 DSPAddress startAddress, 00900 int skipFactor, 00901 int wordCount); 00902 00903 MKDSP_API int DSPReadDoubleArray(double *doubleArray, 00904 DSPMemorySpace memorySpace, 00905 DSPAddress startAddress, 00906 int skipFactor, 00907 int wordCount); 00908 00909 /************************** TRANSFERS WITHIN THE DSP *************************/ 00910 00911 MKDSP_API int DSPMKBLT(DSPMemorySpace memorySpace, 00912 DSPAddress sourceAddr, 00913 DSPAddress destinationAddr, 00914 int wordCount); 00915 00916 MKDSP_API int DSPMKBLTB(DSPMemorySpace memorySpace, 00917 DSPAddress sourceAddr, 00918 DSPAddress destinationAddr, 00919 int wordCount); 00920 00921 MKDSP_API int DSPMKBLTSkipTimed(DSPFix48 *timeStamp, 00922 DSPMemorySpace memorySpace, 00923 DSPAddress srcAddr, 00924 DSPFix24 srcSkip, 00925 DSPAddress dstAddr, 00926 DSPFix24 dstSkip, 00927 DSPFix24 wordCount); 00928 00929 MKDSP_API int DSPMKBLTTimed(DSPFix48 *timeStamp, 00930 DSPMemorySpace memorySpace, 00931 DSPAddress sourceAddr, 00932 DSPAddress destinationAddr, 00933 DSPFix24 wordCount); 00934 00935 MKDSP_API int DSPMKBLTBTimed(DSPFix48 *timeStamp, 00936 DSPMemorySpace memorySpace, 00937 DSPAddress sourceAddr, 00938 DSPAddress destinationAddr, 00939 DSPFix24 wordCount); 00940 00941 MKDSP_API int DSPMKSendBLT(DSPMemorySpace memorySpace, 00942 DSPAddress sourceAddr, 00943 DSPAddress destinationAddr, 00944 DSPFix24 wordCount); 00945 00946 MKDSP_API int DSPMKSendBLTB(DSPMemorySpace memorySpace, 00947 DSPAddress sourceAddr, 00948 DSPAddress destinationAddr, 00949 DSPFix24 wordCount); 00950 00951 00952 /******************** GETTING DSP MEMORY ADDRESSES **************************/ 00953 00954 /* 00955 * The DSP memory addresses are obtained directly from the DSPLoadSpec 00956 * struct registered by DSPBoot() as the currently loaded DSP system. 00957 * The memory boundary symbol names must follow the conventions used 00958 * in the Music Kit and array processing DSP monitors. 00959 * /usr/include/dsp/dsp_memory_map_*.h for a description of the name 00960 * convention, and see /usr/local/lib/dsp/monitor/apmon_8k.lod for an example 00961 * system file which properly defines the address-boundary symbols. 00962 * 00963 * Note that the DSP symbols relied upon below constitute the set of 00964 * symbols any new DSP monitor should export for compatibility with libdsp. 00965 * 00966 * All of these routines return -1 (an impossible address) on error. 00967 */ 00968 00969 MKDSP_API DSPAddress DSPGetLowestInternalUserXAddress(void); 00970 /* Returns DSPGetSystemSymbolValue("XLI_USR") */ 00971 00972 MKDSP_API DSPAddress DSPGetHighestInternalUserXAddress(void); 00973 /* Returns DSPGetSystemSymbolValue("XHI_USR") */ 00974 00975 MKDSP_API DSPAddress DSPGetLowestInternalUserYAddress(void); 00976 /* Returns DSPGetSystemSymbolValue("YLI_USR") */ 00977 00978 MKDSP_API DSPAddress DSPGetHighestInternalUserYAddress(void); 00979 /* Returns DSPGetSystemSymbolValue("YHI_USR") */ 00980 00981 MKDSP_API DSPAddress DSPGetLowestInternalUserPAddress(void); 00982 /* Returns DSPGetSystemSymbolValue("PLI_USR") */ 00983 00984 MKDSP_API DSPAddress DSPGetHighestInternalUserPAddress(void); 00985 /* Returns DSPGetSystemSymbolValue("PHI_USR") */ 00986 00987 MKDSP_API DSPAddress DSPGetLowestExternalUserXAddress(void); 00988 /* Returns DSPGetSystemSymbolValue("XLE_USR") */ 00989 00990 MKDSP_API DSPAddress DSPGetHighestExternalUserXAddress(void); 00991 /* Returns DSPGetSystemSymbolValue("XHE_USR") */ 00992 00993 MKDSP_API DSPAddress DSPGetLowestExternalUserYAddress(void); 00994 /* Returns DSPGetSystemSymbolValue("YLE_USR") */ 00995 00996 MKDSP_API DSPAddress DSPGetHighestExternalUserYAddress(void); 00997 /* Returns DSPGetSystemSymbolValue("YHE_USR") */ 00998 00999 MKDSP_API DSPAddress DSPGetLowestExternalUserPAddress(void); 01000 /* Returns DSPGetSystemSymbolValue("PLE_USR") */ 01001 01002 MKDSP_API DSPAddress DSPGetHighestExternalUserPAddress(void); 01003 /* Returns DSPGetSystemSymbolValue("PHE_USR") */ 01004 01005 MKDSP_API DSPAddress DSPGetHighestExternalUserAddress(void); 01006 /* Returns DSPGetSystemSymbolValue("HE_USR") */ 01007 01008 MKDSP_API DSPAddress DSPGetLowestExternalUserAddress(void); 01009 /* Returns DSPGetSystemSymbolValue("LE_USR") */ 01010 01011 DSPAddress DSPGetLowestXYPartitionUserAddress(void); 01012 /* Returns DSPGetSystemSymbolValue("XLE_USG") */ 01013 01014 DSPAddress DSPGetHighestXYPartitionXUserAddress(void); 01015 /* Returns DSPGetSystemSymbolValue("XHE_USG") */ 01016 01017 DSPAddress DSPGetHighestXYPartitionYUserAddress(void); 01018 /* Returns DSPGetSystemSymbolValue("YHE_USG") */ 01019 01020 DSPAddress DSPGetHighestXYPartitionUserAddress(void); 01021 /* Returns MIN(DSPGetHighestXYPartitionXUserAddress(), 01022 * DSPGetHighestXYPartitionYUserAddress()); 01023 */ 01024 01025 MKDSP_API DSPAddress DSPGetLowestDegMonAddress(void); 01026 /* Returns DSPGetSystemSymbolValue("DEGMON_L") */ 01027 01028 MKDSP_API DSPAddress DSPGetHighestDegMonAddress(void); 01029 /* Returns DSPGetSystemSymbolValue("DEGMON_H") */ 01030 01031 MKDSP_API DSPAddress DSPMKGetClipCountXAddress(void); 01032 /* 01033 * Returns DSPGetSystemSymbolValue("X_NCLIP"). This is the address of the 01034 * location in DSP X memory used to store a cumulative count of "clips". A 01035 * "clip" occurs when an oversized value is moved from the DSP ALU to DSP 01036 * memory. The clip value is reset to zero when the DSP is rebooted. 01037 * A standard usage is to do a timed peek on this location at the end of 01038 * a performance (using DSPMKRetValueTimed()). 01039 */ 01040 01041 #endif