MusicKit  0.0.0
DSPTransfer.h
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