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