00001 #ifndef __MK_DSPMessage_H___ 00002 #define __MK_DSPMessage_H___ 00003 /* DSPMessage.h - procedure prototypes having to do with DSP messages. 00004 * Copyright 1988-1992, NeXT Inc. All rights reserved. 00005 * Author: Julius O. Smith III 00006 */ 00007 00008 #include "MKDSPDefines.h" 00009 00010 /******************************** DSP MESSAGES *******************************/ 00011 00012 /* 00013 * Any unsolicited single word written by the DSP to the host (via RX) 00014 * is defined as a "DSP Message". This 24-bit message consist of a high-order 00015 * "opcode" byte, and two low-order "data" bytes. 00016 * 00017 * If "DSPEnableHostMsg()" is called before opening the DSP, 00018 * "Host Message protocol" is used by the DSP driver. In terms of the 00019 * Sound/DSP driver protocol bits, "host message mode" is defined as 00020 * SNDDRIVER_DSP_PROTO_{DSPMSG|DSPERR|HFABORT|RAW}. 00021 * In this mode, RREQ is kept on in the DSP interface, 00022 * and each "DSP message" causes an interrupt in the host. The DSP messages 00023 * are buffered up by the driver. When not using host message protocol, 00024 * RXDF is ignored, and only "data" is assumed to come from the DSP. 00025 * The data does not go into a driver buffer. Instead, the user 00026 * explicitly reads data from the RX register. 00027 * 00028 * Note that "complex DMA mode" also 00029 * forces the driver to "listen" to the DSP. In that case, if an 00030 * unrecognized DSP message comes in (anything other than a DMA request) 00031 * the message goes to the DSP message buffer as in host message protocol 00032 * mode. 00033 * 00034 * In the functions below, those with "Message" in their name are intended 00035 * to be used in host message mode, and those with "Data" in their name 00036 * are intended to be used outside of host message mode. There exist 00037 * functions DSP{Set,Clear}HostMessageMode() for toggling between the two 00038 * states dynamically (i.e., while the DSP is open). 00039 * 00040 * The following macro 00041 * 00042 * #import "/LocalDeveloper/Headers/dsp/dsp.h" 00043 * #import <sound/sound.h> 00044 * #define DSP_CAN_INTERRUPT ( !(DSPGetProtocol() & SNDDRIVER_DSP_PROTO_RAW) \ 00045 * || (DSPGetProtocol() \ 00046 * & (SNDDRIVER_DSP_PROTO_DSPMSG | SNDDRIVER_DSP_PROTO_C_DMA)) \ 00047 * ) 00048 * 00049 * can be used as follows, for example: 00050 * 00051 * if (DSP_CAN_INTERRUPT) 00052 * return DSPReadMessages(msTimeLimit? msTimeLimit : _DSP_MACH_FOREVER); 00053 * else 00054 * return DSPAwaitCondition((DSP_ISR_RXDF<<8), 00055 * (DSP_ISR_RXDF<<8), 00056 * msTimeLimit); 00057 * 00058 */ 00059 00060 MKDSP_API int DSPDataIsAvailable(void); 00061 /* 00062 * Return nonzero if RXDF is set. 00063 */ 00064 00065 MKDSP_API int DSPAwaitData(int msTimeLimit); 00066 /* 00067 * Block until RXDF is set in the DSP host interface. 00068 * An msTimeLimit of zero means wait forever. 00069 * Returns 0 when data available, nonzero if 00070 * no data available before time-out. 00071 */ 00072 00073 MKDSP_API int DSPMessageIsAvailable(void); 00074 /* 00075 * Return nonzero if DSP has one or more pending DSP messages waiting in the 00076 * DSP host interface. 00077 * Only useable in host message protocol mode or to look for unrecognized 00078 * messages in complex DMA mode. 00079 */ 00080 00081 MKDSP_API int DSPAwaitMessages(int msTimeLimit); 00082 /* 00083 * Block until DSPMessageIsAvailable() will return nonzero. 00084 * An msTimeLimit of zero means wait forever. 00085 * Returns 0 when a message is available, nonzero on time-out. 00086 * Only useable in host message protocol mode. 00087 */ 00088 00089 MKDSP_API int DSPReadMessages(int msTimeLimit); 00090 /* 00091 * Read messages from DSP into internal buffers. 00092 * Returns 0 if DSP messages were read by msTimeLimit milliseconds. 00093 * A 0 msTimeLimit means DON'T WAIT if there are no messages waiting 00094 * from the DSP. See DSPMessage.h for functions which process the messages. 00095 * Only useable in host message protocol mode or to look for unrecognized 00096 * messages in complex DMA mode. 00097 */ 00098 00099 MKDSP_API int DSPMessageGet(int *msgp); 00100 /* 00101 * Return a single DSP message in *msgp, if one is waiting, 00102 * otherwise wait DSPDefaultTimeLimit for it (0 => wait forever). 00103 * On time-out, returns the DSP error code DSP_ENOMSG. 00104 * The DSP message returned in *msgp is 24 bits, right justified. 00105 * Only called when a message is really expected. 00106 * Use DSPAwaitMessages(msTimeLimit) to obtain a precise time-limit. 00107 * Use DSPMessageIsAvailable() to determine if a message is waiting. 00108 */ 00109 00110 MKDSP_API int DSPFlushMessages(void); 00111 /* 00112 * Flush any unread messages from the DSP. 00113 */ 00114 00115 MKDSP_API int DSPFlushMessageBuffer(void); 00116 /* 00117 * Flush any DSP messages cached internally in libdsp. 00118 * Same as DSPFlushMessages() except that the DSP 00119 * is not checked for more messages. Anything 00120 * queued up in the driver buffer will stay there. 00121 * Use DSPFlushMessages() to flush the driver's message queue. 00122 * Note: since there is no input-data buffer in the driver, 00123 * there is no DSPFlushDataBuffer() function. 00124 */ 00125 00126 00127 MKDSP_API int DSPBreakPoint(int dsp_bp_msg); 00128 /* 00129 * Process a breakpoint generated by DSP software. A "breakpoint" is just a 00130 * "DSP message" with an op-code of 0x80. 00131 * It currently just prints the DSP breakpoint message, reads any messages 00132 * trying to get out of the DSP, and pauses so that the Ariel debugger (Bug56) 00133 * can be used to see what's going on before anything else happens. 00134 * Only useable in host message protocol mode. 00135 */ 00136 00137 00138 MKDSP_API int DSPMessagesOff(void); 00139 /* 00140 * Turn off DSP messages at their source in the DSP. The messages will pile 00141 * up in the DSP until its "DSP Message Queue" (DMQ) fills up, unless the 00142 * host message DSP_HM_BLOCK_OFF was sent to it. The Music Kit and array 00143 * processing DSP monitors support this protocol. 00144 */ 00145 00146 00147 MKDSP_API int DSPMessagesOn(void); 00148 /* 00149 * Enable DSP messages in the MK or AP monitor (on by default). 00150 */ 00151 00152 00153 MKDSP_API int DSPMessageGet(int *msgp); 00154 /* 00155 * Return a single DSP message in *msgp, if one is waiting, 00156 * otherwise it returns the DSP error code DSP_ENOMSG. 00157 * The DSP message returned in *msgp is 24 bits, right justified. 00158 */ 00159 00160 00161 MKDSP_API int DSPAwaitAnyMessage( 00162 int *dspackp, /* returned DSP message */ 00163 int msTimeLimit); /* time-out in milliseconds */ 00164 /* 00165 * Await any message from the DSP. 00166 */ 00167 00168 00169 MKDSP_API int DSPAwaitUnsignedReply( 00170 DSPAddress opcode, /* opcode of expected DSP message */ 00171 DSPFix24 *datum, /* datum of expected DSP message (returned) */ 00172 int msTimeLimit); /* time-out in milliseconds */ 00173 /* 00174 * Wait for specific DSP message containing an unsigned datum. 00175 */ 00176 00177 00178 MKDSP_API int DSPAwaitSignedReply( 00179 DSPAddress opcode, /* opcode of expected DSP message */ 00180 int *datum, /* datum of expected DSP message (returned) */ 00181 int msTimeLimit); /* time-out in milliseconds */ 00182 /* 00183 * Wait for specific DSP message containing a signed datum. 00184 */ 00185 00186 00187 MKDSP_API int DSPAwaitMessage( 00188 DSPAddress opcode, /* opcode of expected DSP message */ 00189 int msTimeLimit); /* time-out in milliseconds */ 00190 /* 00191 * Return specific DSP message, declaring any others as errors. 00192 */ 00193 00194 00195 MKDSP_API int DSPHostMessage(int msg); 00196 /* 00197 * Issue untimed DSP "host message" (minus args) by issuing "xhm" 00198 * host command. Example: DSPHostMessage(DSP_HM_ABORT). 00199 */ 00200 00201 00202 MKDSP_API int DSPMKHostMessageTimed(DSPFix48 *aTimeStampP, int msg); 00203 00204 /* 00205 * Issue timed or untimed DSP "host message" (0 args) by issuing "xhm" 00206 * host command. Example: DSPMKHostMessageTimed(aTimeStampP,DSP_HM_ABORT). 00207 */ 00208 00209 00210 MKDSP_API int DSPMKHostMessageTimedFromInts( 00211 int msg, /* Host message opcode. */ 00212 int hiwd, /* High word of time stamp. */ 00213 int lowd); /* Lo word of time stamp. */ 00214 /* 00215 * Same as DSPMKHostMessageTimed(), but taking time stamp from ints 00216 * instead of a DSPFix48 struct. 00217 */ 00218 00219 00220 MKDSP_API int DSPCall( 00221 DSPAddress hm_opcode, 00222 int nArgs, 00223 DSPFix24 *argArray); 00224 /* 00225 * Send an untimed host message to the DSP. 00226 */ 00227 00228 00229 MKDSP_API int DSPCallB( 00230 DSPAddress hm_opcode, 00231 int nArgs, 00232 DSPFix24 *argArray); 00233 /* 00234 * Same as DSPCall() except that the argArray is sent in reverse 00235 * order to the DSP. 00236 */ 00237 00238 00239 MKDSP_API int DSPCallV(DSPAddress hm_opcode,int nArgs,...); 00240 /* 00241 * Usage is int DSPCallV(hm_opcode,nArgs,arg1,...,ArgNargs); 00242 * Same as DSPCall() except that a variable number of host message arguments 00243 * is specified explicitly (using varargs) rather than being passed in an 00244 * array. 00245 */ 00246 00247 00248 MKDSP_API int DSPMKStartReaders(void); 00249 /* 00250 * Start error and message readers. 00251 * Called by DSPMKInit() after DSPBoot(). 00252 * Necessary to field and discard "kernel acks" from the DSP 00253 * during a performance. 00254 */ 00255 00256 MKDSP_API int DSPMKStopMsgReader(void); 00257 /* 00258 * Stop message reader. Error reader is stopped by closing DSP. 00259 * The Music Kit calls this before waiting for requesting a 00260 * message at the end of time. 00261 */ 00262 00263 MKDSP_API int DSPMKFlushTimedMessages(void); 00264 /* 00265 * Flush all combined timed messages for the current time. 00266 * You must send this if you are sending updates to the DSP 00267 * asynchronously (e.g. in response to mouse events 00268 * as opposed to via the Music Kit Conductor). The Music Kit 00269 * automatically calls it for Conductor and MIDI events. 00270 */ 00271 00272 MKDSP_API int DSPMKCallTimed( 00273 DSPFix48 *aTimeStampP, 00274 DSPAddress hm_opcode, 00275 int nArgs, 00276 DSPFix24 *argArray); 00277 /* 00278 * Enqueue a timed host message for the DSP. If the time stamp of the 00279 * host message is greater than that of the host messages currently 00280 * in the timed message buffer, the buffer is flushed before the 00281 * new message is enqueued. If the timed stamp is equal to those 00282 * currently in the buffer, it is appended to the buffer. It is an 00283 * error for the time stamp to be less than that of the current 00284 * timed message buffer, unless it is zero; a zero time stamp means 00285 * execute the message at the end of the current "tick" in the DSP. 00286 * If aTimeStamp is NULL, the host message is executed untimed. 00287 */ 00288 00289 00290 MKDSP_API int DSPMKCallTimedV(DSPFix48 *aTimeStampP,int hm_opcode,int nArgs,...); 00291 /* 00292 * Usage is int DSPMKCallTimedV(aTimeStampP,hm_opcode,nArgs,arg1,...,ArgNargs); 00293 * Same as DSPMKCallTimed() except that a variable number of host message 00294 * arguments is specified explicitly in the argument list (using stdarg) 00295 * rather than being passed in an array. 00296 */ 00297 00298 MKDSP_API int DSPMKAwaitEndOfTime(DSPFix48 *aTimeStampP); 00299 /* 00300 * Issues a timed message for the specified time, then blocks until that message 00301 * is received. 00302 */ 00303 00304 #endif