MusicKit  0.0.0
DSPTransfer.h
00001 #ifndef __MK_DSPTransfer_H___
00002 #define __MK_DSPTransfer_H___
00003 /* $Id$
00004  * Functions in libdsp_s.a having to do with data transfer.
00005  * Copyright 1988-1992, NeXT Inc.  All rights reserved.
00006  * Author: Julius O. Smith III
00007  */
00008 
00009 #if 0
00010 
00011  TERMINOLOGY
00012 
00013     A "load" is an immediate transfer of a DSPLoadSpec struct into DSP memory.
00014     A load can occur any time after DSPBoot() or DSP{AP,MK,}Init().
00015 
00016     A "write" is an immediate transfer into DSP memory,
00017     normally used to download user data to the DSP.
00018 
00019     A "read" is the inverse of a "write".   The transfer is immediate,
00020     without regard for DSP time, if any. 
00021 
00022     A "get" is the same as a "read", except that the return value of the
00023     function contains the desired datum rather than an error code.
00024 
00025     A "vector" is a contiguous array of words.  A one-dimensional 
00026     (singly subscripted) C array is an example of a vector.
00027 
00028     An "array" is a not-necessarily-contiguous sequence of words.
00029     An array is specified by a vector plus a "skip factor".
00030 
00031     A "skip factor" is the number of array elements to advance in an 
00032     array transfer.  An array with a skip factor of 1 is equivalent to
00033     a vector.  A skip factor of 2 means take every other element when
00034     reading from the DSP and write every other element when writing to
00035     the DSP.  A skip factor of 3 means skip 2 elements between each
00036     read or write, and so on.
00037 
00038     ----------------------------------------------------------------------
00039 
00040     The following terms pertain primarily to the Music Kit DSP monitor:
00041 
00042     A "send" is a timed transfer into DSP memory.  Functions which do
00043     "sends" have prefix "DSPMKSend..." or have the form "DSPMK...Timed()".
00044 
00045     A "ret{rieve}" is the inverse of a "send".  
00046 
00047     A "tick" is DSPMK_I_NTICK samples of digital audio produced by one
00048     iteration of the "orchestra loop" in the DSP.
00049 
00050     An "immediate send" is a send in which the time stamp is 0.  The global
00051     variable DSPTimeStamp0 exists for specifying a zero time stamp.  It 
00052     results in a tick-synchronized write, i.e., occurring at end of
00053     current tick in the DSP.
00054 
00055     An orchestra must be running on the chip to do either type of send.  
00056     Time-stamped DSP directives are always used in the context of the
00057     Music Kit orchestra.
00058 
00059     If the time stamp pointer is null (DSPMK_UNTIMED), then a send reduces 
00060     to a write.
00061 
00062     A "BLT" (BLock Transfer) is a move within DSP memory.
00063     A "BLTB" is a Backwards move within DSP memory.
00064 
00065     A "fill" specifies one value to use in filling DSP memory.
00066 
00067 #endif
00068 
00069 
00070 /****************** READING/WRITING HOST-INTERFACE REGISTERS *****************/
00071 
00072 
00073 extern 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 extern unsigned int DSPGetRegs(void);
00084 /*
00085  * Same as DSPReadRegs() but returns regs as function value.
00086  */
00087 
00088 
00089 extern 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 extern 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 extern int DSPGetICR(void);
00111 /*
00112  * Return ICR register of the DSP host interface.
00113  */
00114 
00115 
00116 extern 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 extern int DSPGetCVR(void);
00124 /*
00125  * Return CVR register of the DSP host interface.
00126  */
00127 
00128 
00129 extern 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 extern 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 extern int DSPGetISR(void);
00146 /*
00147  * Return ISR register of the DSP host interface.
00148  */
00149 
00150 
00151 extern int DSPGetRX(void);
00152 /*
00153  * Return RX register of the DSP host interface.
00154  * Equivalent to "DSPReadRX(&tmp); return tmp;".
00155  */
00156 
00157 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern int DSPWriteTXArray(
00238     DSPFix24 *data,
00239     int nwords);
00240 /* 
00241  * Feed array to DSP transmit register.
00242  */
00243 
00244 
00245 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern int DSPMKSendLong(DSPFix48 *aFix48Val, int addr);
00561 /*
00562  * etc.
00563  */
00564 
00565 
00566 extern int DSPMKSendLongTimed(DSPFix48 *aTimeStampP, 
00567                               DSPFix48 *aFix48Val,
00568                               int addr);
00569 
00570 
00571 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern int DSPMKSendMemoryClear(DSPMemorySpace space,
00721                                 DSPAddress address,
00722                                 int count);
00723 
00724 extern int DSPMKMemoryClearTimed(DSPFix48 *aTimeStampP, 
00725                                  DSPMemorySpace space,
00726                                  DSPAddress address,
00727                                  int count);
00728 
00729 /****************************  Poking DSP Symbols ****************************/
00730 
00731 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern 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 extern int DSPReadFloatArray(float *floatArray,
00898                              DSPMemorySpace memorySpace,
00899                              DSPAddress startAddress,
00900                              int skipFactor,
00901                              int wordCount);
00902 
00903 extern int DSPReadDoubleArray(double *doubleArray,
00904                               DSPMemorySpace memorySpace,
00905                               DSPAddress startAddress,
00906                               int skipFactor,
00907                               int wordCount);
00908 
00909 /************************** TRANSFERS WITHIN THE DSP *************************/
00910 
00911 extern int DSPMKBLT(DSPMemorySpace memorySpace,
00912                     DSPAddress sourceAddr,
00913                     DSPAddress destinationAddr,
00914                     int wordCount);
00915 
00916 extern int DSPMKBLTB(DSPMemorySpace memorySpace,
00917                      DSPAddress sourceAddr,
00918                      DSPAddress destinationAddr,
00919                      int wordCount);
00920 
00921 extern int DSPMKBLTSkipTimed(DSPFix48 *timeStamp,
00922                              DSPMemorySpace memorySpace,
00923                              DSPAddress srcAddr,
00924                              DSPFix24 srcSkip,
00925                              DSPAddress dstAddr,
00926                              DSPFix24 dstSkip,
00927                              DSPFix24 wordCount);
00928 
00929 extern int DSPMKBLTTimed(DSPFix48 *timeStamp,
00930                          DSPMemorySpace memorySpace,
00931                          DSPAddress sourceAddr,
00932                          DSPAddress destinationAddr,
00933                          DSPFix24 wordCount);
00934 
00935 extern int DSPMKBLTBTimed(DSPFix48 *timeStamp,
00936                           DSPMemorySpace memorySpace,
00937                           DSPAddress sourceAddr,
00938                           DSPAddress destinationAddr,
00939                           DSPFix24 wordCount);
00940 
00941 extern int DSPMKSendBLT(DSPMemorySpace memorySpace,
00942                         DSPAddress sourceAddr,
00943                         DSPAddress destinationAddr,
00944                         DSPFix24 wordCount);
00945 
00946 extern 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 extern DSPAddress DSPGetLowestInternalUserXAddress(void);
00970 /* Returns DSPGetSystemSymbolValue("XLI_USR") */
00971 
00972 extern DSPAddress DSPGetHighestInternalUserXAddress(void);
00973 /* Returns DSPGetSystemSymbolValue("XHI_USR") */
00974 
00975 extern DSPAddress DSPGetLowestInternalUserYAddress(void);
00976 /* Returns DSPGetSystemSymbolValue("YLI_USR") */
00977 
00978 extern DSPAddress DSPGetHighestInternalUserYAddress(void);
00979 /* Returns DSPGetSystemSymbolValue("YHI_USR") */
00980 
00981 extern DSPAddress DSPGetLowestInternalUserPAddress(void);
00982 /* Returns DSPGetSystemSymbolValue("PLI_USR") */
00983 
00984 extern DSPAddress DSPGetHighestInternalUserPAddress(void);
00985 /* Returns DSPGetSystemSymbolValue("PHI_USR") */
00986 
00987 extern DSPAddress DSPGetLowestExternalUserXAddress(void);
00988 /* Returns DSPGetSystemSymbolValue("XLE_USR") */
00989 
00990 extern DSPAddress DSPGetHighestExternalUserXAddress(void);
00991 /* Returns DSPGetSystemSymbolValue("XHE_USR") */
00992 
00993 extern DSPAddress DSPGetLowestExternalUserYAddress(void);
00994 /* Returns DSPGetSystemSymbolValue("YLE_USR") */
00995 
00996 extern DSPAddress DSPGetHighestExternalUserYAddress(void);
00997 /* Returns DSPGetSystemSymbolValue("YHE_USR") */
00998 
00999 extern DSPAddress DSPGetLowestExternalUserPAddress(void);
01000 /* Returns DSPGetSystemSymbolValue("PLE_USR") */
01001 
01002 extern DSPAddress DSPGetHighestExternalUserPAddress(void);
01003 /* Returns DSPGetSystemSymbolValue("PHE_USR") */
01004 
01005 extern DSPAddress DSPGetHighestExternalUserAddress(void);
01006 /* Returns DSPGetSystemSymbolValue("HE_USR") */
01007 
01008 extern 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 extern DSPAddress DSPGetLowestDegMonAddress(void);
01026 /* Returns DSPGetSystemSymbolValue("DEGMON_L") */
01027 
01028 extern DSPAddress DSPGetHighestDegMonAddress(void);
01029 /* Returns DSPGetSystemSymbolValue("DEGMON_H") */
01030 
01031 extern 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