ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/audio.cpp
Revision: 1.16
Committed: 2008-01-01T09:40:31Z (16 years, 4 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.15: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * audio.cpp - Audio support
3 *
4 * Basilisk II (C) 1997-2008 Christian Bauer
5 * Portions written by Marc Hellwig
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 /*
23 * SEE ALSO
24 * Inside Macintosh: Sound, chapter 5 "Sound Components"
25 */
26
27 #include "sysdeps.h"
28 #include "cpu_emulation.h"
29 #include "macos_util.h"
30 #include "emul_op.h"
31 #include "main.h"
32 #include "audio.h"
33 #include "audio_defs.h"
34
35 #define DEBUG 0
36 #include "debug.h"
37
38
39 // Supported sample rates, sizes and channels
40 vector<uint32> audio_sample_rates;
41 vector<uint16> audio_sample_sizes;
42 vector<uint16> audio_channel_counts;
43
44 // Global variables
45 struct audio_status AudioStatus; // Current audio status (sample rate etc.)
46 bool audio_open = false; // Flag: audio is initialized and ready
47 int audio_frames_per_block; // Number of audio frames per block
48 uint32 audio_component_flags; // Component feature flags
49 uint32 audio_data = 0; // Mac address of global data area
50 static int open_count = 0; // Open/close nesting count
51
52 bool AudioAvailable = false; // Flag: audio output available (from the software point of view)
53
54
55 /*
56 * Reset audio emulation
57 */
58
59 void AudioReset(void)
60 {
61 audio_data = 0;
62 }
63
64
65 /*
66 * Get audio info
67 */
68
69 static int32 AudioGetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
70 {
71 D(bug(" AudioGetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
72 M68kRegisters r;
73
74 switch (selector) {
75 case siSampleSize:
76 WriteMacInt16(infoPtr, AudioStatus.sample_size);
77 break;
78
79 case siSampleSizeAvailable: {
80 r.d[0] = audio_sample_sizes.size() * 2;
81 Execute68kTrap(0xa122, &r); // NewHandle()
82 uint32 h = r.a[0];
83 if (h == 0)
84 return memFullErr;
85 WriteMacInt16(infoPtr + sil_count, audio_sample_sizes.size());
86 WriteMacInt32(infoPtr + sil_infoHandle, h);
87 uint32 sp = ReadMacInt32(h);
88 for (unsigned i=0; i<audio_sample_sizes.size(); i++)
89 WriteMacInt16(sp + i*2, audio_sample_sizes[i]);
90 break;
91 }
92
93 case siNumberChannels:
94 WriteMacInt16(infoPtr, AudioStatus.channels);
95 break;
96
97 case siChannelAvailable: {
98 r.d[0] = audio_channel_counts.size() * 2;
99 Execute68kTrap(0xa122, &r); // NewHandle()
100 uint32 h = r.a[0];
101 if (h == 0)
102 return memFullErr;
103 WriteMacInt16(infoPtr + sil_count, audio_channel_counts.size());
104 WriteMacInt32(infoPtr + sil_infoHandle, h);
105 uint32 sp = ReadMacInt32(h);
106 for (unsigned i=0; i<audio_channel_counts.size(); i++)
107 WriteMacInt16(sp + i*2, audio_channel_counts[i]);
108 break;
109 }
110
111 case siSampleRate:
112 WriteMacInt32(infoPtr, AudioStatus.sample_rate);
113 break;
114
115 case siSampleRateAvailable: {
116 r.d[0] = audio_sample_rates.size() * 4;
117 Execute68kTrap(0xa122, &r); // NewHandle()
118 uint32 h = r.a[0];
119 if (h == 0)
120 return memFullErr;
121 WriteMacInt16(infoPtr + sil_count, audio_sample_rates.size());
122 WriteMacInt32(infoPtr + sil_infoHandle, h);
123 uint32 lp = ReadMacInt32(h);
124 for (unsigned i=0; i<audio_sample_rates.size(); i++)
125 WriteMacInt32(lp + i*4, audio_sample_rates[i]);
126 break;
127 }
128
129 case siSpeakerMute:
130 WriteMacInt16(infoPtr, audio_get_speaker_mute());
131 break;
132
133 case siSpeakerVolume:
134 WriteMacInt32(infoPtr, audio_get_speaker_volume());
135 break;
136
137 case siHardwareMute:
138 WriteMacInt16(infoPtr, audio_get_main_mute());
139 break;
140
141 case siHardwareVolume:
142 WriteMacInt32(infoPtr, audio_get_main_volume());
143 break;
144
145 case siHardwareVolumeSteps:
146 WriteMacInt16(infoPtr, 7);
147 break;
148
149 case siHardwareBusy:
150 WriteMacInt16(infoPtr, AudioStatus.num_sources != 0);
151 break;
152
153 case siHardwareFormat:
154 WriteMacInt32(infoPtr + scd_flags, 0);
155 WriteMacInt32(infoPtr + scd_format, AudioStatus.sample_size == 16 ? FOURCC('t','w','o','s') : FOURCC('r','a','w',' '));
156 WriteMacInt16(infoPtr + scd_numChannels, AudioStatus.channels);
157 WriteMacInt16(infoPtr + scd_sampleSize, AudioStatus.sample_size);
158 WriteMacInt32(infoPtr + scd_sampleRate, AudioStatus.sample_rate);
159 WriteMacInt32(infoPtr + scd_sampleCount, audio_frames_per_block);
160 WriteMacInt32(infoPtr + scd_buffer, 0);
161 WriteMacInt32(infoPtr + scd_reserved, 0);
162 break;
163
164 default: // Delegate to Apple Mixer
165 if (AudioStatus.mixer == 0)
166 return badComponentSelector;
167 M68kRegisters r;
168 r.a[0] = infoPtr;
169 r.d[0] = selector;
170 r.a[1] = sourceID;
171 r.a[2] = AudioStatus.mixer;
172 Execute68k(audio_data + adatGetInfo, &r);
173 D(bug(" delegated to Apple Mixer, returns %08lx\n", r.d[0]));
174 return r.d[0];
175 }
176 return noErr;
177 }
178
179
180 /*
181 * Set audio info
182 */
183
184 static int32 AudioSetInfo(uint32 infoPtr, uint32 selector, uint32 sourceID)
185 {
186 D(bug(" AudioSetInfo %c%c%c%c, infoPtr %08lx, source ID %08lx\n", selector >> 24, (selector >> 16) & 0xff, (selector >> 8) & 0xff, selector & 0xff, infoPtr, sourceID));
187 M68kRegisters r;
188
189 switch (selector) {
190 case siSampleSize:
191 D(bug(" set sample size %08lx\n", infoPtr));
192 if (AudioStatus.num_sources)
193 return siDeviceBusyErr;
194 if (infoPtr == AudioStatus.sample_size)
195 return noErr;
196 for (unsigned i=0; i<audio_sample_sizes.size(); i++)
197 if (audio_sample_sizes[i] == infoPtr) {
198 if (audio_set_sample_size(i))
199 return noErr;
200 else
201 return siInvalidSampleSize;
202 }
203 return siInvalidSampleSize;
204
205 case siSampleRate:
206 D(bug(" set sample rate %08lx\n", infoPtr));
207 if (AudioStatus.num_sources)
208 return siDeviceBusyErr;
209 if (infoPtr == AudioStatus.sample_rate)
210 return noErr;
211 for (unsigned i=0; i<audio_sample_rates.size(); i++)
212 if (audio_sample_rates[i] == infoPtr) {
213 if (audio_set_sample_rate(i))
214 return noErr;
215 else
216 return siInvalidSampleRate;
217 }
218 return siInvalidSampleRate;
219
220 case siNumberChannels:
221 D(bug(" set number of channels %08lx\n", infoPtr));
222 if (AudioStatus.num_sources)
223 return siDeviceBusyErr;
224 if (infoPtr == AudioStatus.channels)
225 return noErr;
226 for (unsigned i=0; i<audio_channel_counts.size(); i++)
227 if (audio_channel_counts[i] == infoPtr) {
228 if (audio_set_channels(i))
229 return noErr;
230 else
231 return badChannel;
232 }
233 return badChannel;
234
235 case siSpeakerMute:
236 audio_set_speaker_mute((uint16)infoPtr);
237 break;
238
239 case siSpeakerVolume:
240 D(bug(" set speaker volume %08lx\n", infoPtr));
241 audio_set_speaker_volume(infoPtr);
242 break;
243
244 case siHardwareMute:
245 audio_set_main_mute((uint16)infoPtr);
246 break;
247
248 case siHardwareVolume:
249 D(bug(" set hardware volume %08lx\n", infoPtr));
250 audio_set_main_volume(infoPtr);
251 break;
252
253 default: // Delegate to Apple Mixer
254 if (AudioStatus.mixer == 0)
255 return badComponentSelector;
256 r.a[0] = infoPtr;
257 r.d[0] = selector;
258 r.a[1] = sourceID;
259 r.a[2] = AudioStatus.mixer;
260 Execute68k(audio_data + adatSetInfo, &r);
261 D(bug(" delegated to Apple Mixer, returns %08lx\n", r.d[0]));
262 return r.d[0];
263 }
264 return noErr;
265 }
266
267
268 /*
269 * Sound output component dispatch
270 */
271
272 int32 AudioDispatch(uint32 params, uint32 globals)
273 {
274 D(bug("AudioDispatch params %08lx (size %d), what %d\n", params, ReadMacInt8(params + cp_paramSize), (int16)ReadMacInt16(params + cp_what)));
275 M68kRegisters r;
276 uint32 p = params + cp_params;
277 int16 selector = (int16)ReadMacInt16(params + cp_what);
278
279 switch (selector) {
280
281 // General component functions
282 case kComponentOpenSelect:
283 if (audio_data == 0) {
284
285 // Allocate global data area
286 r.d[0] = SIZEOF_adat;
287 Execute68kTrap(0xa040, &r); // ResrvMem()
288 r.d[0] = SIZEOF_adat;
289 Execute68kTrap(0xa31e, &r); // NewPtrClear()
290 if (r.a[0] == 0)
291 return memFullErr;
292 audio_data = r.a[0];
293 D(bug(" global data at %08lx\n", audio_data));
294
295 // Put in 68k routines
296 int p = audio_data + adatDelegateCall;
297 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
298 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
299 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
300 WriteMacInt16(p, 0x7024); p += 2; // moveq #$24,d0
301 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
302 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
303 WriteMacInt16(p, M68K_RTS); p += 2; // rts
304 if (p - audio_data != adatOpenMixer)
305 goto adat_error;
306 WriteMacInt16(p, 0x558f); p += 2; // subq.l #2,sp
307 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
308 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
309 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
310 WriteMacInt16(p, 0x203c); p += 2; // move.l #$06140018,d0
311 WriteMacInt32(p, 0x06140018); p+= 4;
312 WriteMacInt16(p, 0xa800); p += 2; // SoundDispatch
313 WriteMacInt16(p, 0x301f); p += 2; // move.w (sp)+,d0
314 WriteMacInt16(p, 0x48c0); p += 2; // ext.l d0
315 WriteMacInt16(p, M68K_RTS); p += 2; // rts
316 if (p - audio_data != adatCloseMixer)
317 goto adat_error;
318 WriteMacInt16(p, 0x558f); p += 2; // subq.l #2,sp
319 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
320 WriteMacInt16(p, 0x203c); p += 2; // move.l #$02180018,d0
321 WriteMacInt32(p, 0x02180018); p+= 4;
322 WriteMacInt16(p, 0xa800); p += 2; // SoundDispatch
323 WriteMacInt16(p, 0x301f); p += 2; // move.w (sp)+,d0
324 WriteMacInt16(p, 0x48c0); p += 2; // ext.l d0
325 WriteMacInt16(p, M68K_RTS); p += 2; // rts
326 if (p - audio_data != adatGetInfo)
327 goto adat_error;
328 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
329 WriteMacInt16(p, 0x2f0a); p += 2; // move.l a2,-(sp)
330 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
331 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
332 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
333 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$000c0103,-(sp)
334 WriteMacInt32(p, 0x000c0103); p+= 4;
335 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
336 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
337 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
338 WriteMacInt16(p, M68K_RTS); p += 2; // rts
339 if (p - audio_data != adatSetInfo)
340 goto adat_error;
341 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
342 WriteMacInt16(p, 0x2f0a); p += 2; // move.l a2,-(sp)
343 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
344 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
345 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
346 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$000c0104,-(sp)
347 WriteMacInt32(p, 0x000c0104); p+= 4;
348 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
349 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
350 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
351 WriteMacInt16(p, M68K_RTS); p += 2; // rts
352 if (p - audio_data != adatPlaySourceBuffer)
353 goto adat_error;
354 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
355 WriteMacInt16(p, 0x2f0a); p += 2; // move.l a2,-(sp)
356 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
357 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
358 WriteMacInt16(p, 0x2f00); p += 2; // move.l d0,-(sp)
359 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$000c0108,-(sp)
360 WriteMacInt32(p, 0x000c0108); p+= 4;
361 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
362 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
363 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
364 WriteMacInt16(p, M68K_RTS); p += 2; // rts
365 if (p - audio_data != adatGetSourceData)
366 goto adat_error;
367 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
368 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
369 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
370 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$00040004,-(sp)
371 WriteMacInt32(p, 0x00040004); p+= 4;
372 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
373 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
374 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
375 WriteMacInt16(p, M68K_RTS); p += 2; // rts
376 if (p - audio_data != adatStartSource)
377 goto adat_error;
378 WriteMacInt16(p, 0x598f); p += 2; // subq.l #4,sp
379 WriteMacInt16(p, 0x2f09); p += 2; // move.l a1,-(sp)
380 WriteMacInt16(p, 0x3f00); p += 2; // move.w d0,-(sp)
381 WriteMacInt16(p, 0x2f08); p += 2; // move.l a0,-(sp)
382 WriteMacInt16(p, 0x2f3c); p += 2; // move.l #$00060105,-(sp)
383 WriteMacInt32(p, 0x00060105); p+= 4;
384 WriteMacInt16(p, 0x7000); p += 2; // moveq #0,d0
385 WriteMacInt16(p, 0xa82a); p += 2; // ComponentDispatch
386 WriteMacInt16(p, 0x201f); p += 2; // move.l (sp)+,d0
387 WriteMacInt16(p, M68K_RTS); p += 2; // rts
388 if (p - audio_data != adatData)
389 goto adat_error;
390 }
391 AudioAvailable = true;
392 if (open_count == 0)
393 audio_enter_stream();
394 open_count++;
395 return noErr;
396
397 adat_error: printf("FATAL: audio component data block initialization error\n");
398 QuitEmulator();
399 return openErr;
400
401 case kComponentCloseSelect:
402 open_count--;
403 if (open_count == 0) {
404 if (audio_data) {
405 if (AudioStatus.mixer) {
406 // Close Apple Mixer
407 r.a[0] = AudioStatus.mixer;
408 Execute68k(audio_data + adatCloseMixer, &r);
409 AudioStatus.mixer = 0;
410 return r.d[0];
411 }
412 r.a[0] = audio_data;
413 Execute68kTrap(0xa01f, &r); // DisposePtr()
414 audio_data = 0;
415 }
416 AudioStatus.num_sources = 0;
417 audio_exit_stream();
418 }
419 return noErr;
420
421 case kComponentCanDoSelect:
422 switch ((int16)ReadMacInt16(p)) {
423 case kComponentOpenSelect:
424 case kComponentCloseSelect:
425 case kComponentCanDoSelect:
426 case kComponentVersionSelect:
427 case kComponentRegisterSelect:
428 case kSoundComponentInitOutputDeviceSelect:
429 case kSoundComponentGetSourceSelect:
430 case kSoundComponentGetInfoSelect:
431 case kSoundComponentSetInfoSelect:
432 case kSoundComponentStartSourceSelect:
433 return 1;
434 default:
435 return 0;
436 }
437
438 case kComponentVersionSelect:
439 return 0x00010003;
440
441 case kComponentRegisterSelect:
442 return noErr;
443
444 // Sound component functions (not delegated)
445 case kSoundComponentInitOutputDeviceSelect:
446 D(bug(" InitOutputDevice\n"));
447 if (!audio_open)
448 return noHardwareErr;
449 if (AudioStatus.mixer)
450 return noErr;
451
452 // Init sound component data
453 WriteMacInt32(audio_data + adatData + scd_flags, 0);
454 WriteMacInt32(audio_data + adatData + scd_format, AudioStatus.sample_size == 16 ? FOURCC('t','w','o','s') : FOURCC('r','a','w',' '));
455 WriteMacInt16(audio_data + adatData + scd_numChannels, AudioStatus.channels);
456 WriteMacInt16(audio_data + adatData + scd_sampleSize, AudioStatus.sample_size);
457 WriteMacInt32(audio_data + adatData + scd_sampleRate, AudioStatus.sample_rate);
458 WriteMacInt32(audio_data + adatData + scd_sampleCount, audio_frames_per_block);
459 WriteMacInt32(audio_data + adatData + scd_buffer, 0);
460 WriteMacInt32(audio_data + adatData + scd_reserved, 0);
461 WriteMacInt32(audio_data + adatStreamInfo, 0);
462
463 // Open Apple Mixer
464 r.a[0] = audio_data + adatMixer;
465 r.d[0] = 0;
466 r.a[1] = audio_data + adatData;
467 Execute68k(audio_data + adatOpenMixer, &r);
468 AudioStatus.mixer = ReadMacInt32(audio_data + adatMixer);
469 D(bug(" OpenMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer));
470 return r.d[0];
471
472 case kSoundComponentGetSourceSelect:
473 D(bug(" GetSource source %08lx\n", ReadMacInt32(p)));
474 WriteMacInt32(ReadMacInt32(p), AudioStatus.mixer);
475 return noErr;
476
477 // Sound component functions (delegated)
478 case kSoundComponentAddSourceSelect:
479 D(bug(" AddSource\n"));
480 AudioStatus.num_sources++;
481 goto delegate;
482
483 case kSoundComponentRemoveSourceSelect:
484 D(bug(" RemoveSource\n"));
485 AudioStatus.num_sources--;
486 goto delegate;
487
488 case kSoundComponentGetInfoSelect:
489 return AudioGetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
490
491 case kSoundComponentSetInfoSelect:
492 return AudioSetInfo(ReadMacInt32(p), ReadMacInt32(p + 4), ReadMacInt32(p + 8));
493
494 case kSoundComponentStartSourceSelect:
495 D(bug(" StartSource count %d\n", ReadMacInt16(p + 4)));
496 D(bug(" starting Apple Mixer\n"));
497 r.d[0] = ReadMacInt16(p + 4);
498 r.a[0] = ReadMacInt32(p);
499 r.a[1] = AudioStatus.mixer;
500 Execute68k(audio_data + adatStartSource, &r);
501 D(bug(" returns %08lx\n", r.d[0]));
502 return noErr;
503
504 case kSoundComponentStopSourceSelect:
505 D(bug(" StopSource\n"));
506 goto delegate;
507
508 case kSoundComponentPauseSourceSelect:
509 D(bug(" PauseSource\n"));
510 delegate: // Delegate call to Apple Mixer
511 D(bug(" delegating call to Apple Mixer\n"));
512 r.a[0] = AudioStatus.mixer;
513 r.a[1] = params;
514 Execute68k(audio_data + adatDelegateCall, &r);
515 D(bug(" returns %08lx\n", r.d[0]));
516 return r.d[0];
517
518 case kSoundComponentPlaySourceBufferSelect:
519 D(bug(" PlaySourceBuffer flags %08lx\n", ReadMacInt32(p)));
520 r.d[0] = ReadMacInt32(p);
521 r.a[0] = ReadMacInt32(p + 4);
522 r.a[1] = ReadMacInt32(p + 8);
523 r.a[2] = AudioStatus.mixer;
524 Execute68k(audio_data + adatPlaySourceBuffer, &r);
525 D(bug(" returns %08lx\n", r.d[0]));
526 return r.d[0];
527
528 default:
529 if (selector >= 0x100)
530 goto delegate;
531 else
532 return badComponentSelector;
533 }
534 }
535
536
537 /*
538 * Sound input driver Open() routine
539 */
540
541 int16 SoundInOpen(uint32 pb, uint32 dce)
542 {
543 D(bug("SoundInOpen\n"));
544 return noErr;
545 }
546
547
548 /*
549 * Sound input driver Prime() routine
550 */
551
552 int16 SoundInPrime(uint32 pb, uint32 dce)
553 {
554 D(bug("SoundInPrime\n"));
555 //!!
556 return paramErr;
557 }
558
559
560 /*
561 * Sound input driver Control() routine
562 */
563
564 int16 SoundInControl(uint32 pb, uint32 dce)
565 {
566 uint16 code = ReadMacInt16(pb + csCode);
567 D(bug("SoundInControl %d\n", code));
568
569 if (code == 1) {
570 D(bug(" SoundInKillIO\n"));
571 //!!
572 return noErr;
573 }
574
575 if (code != 2)
576 return -231; // siUnknownInfoType
577
578 uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
579 uint32 selector = param[0];
580 D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
581
582 switch (selector) {
583 default:
584 return -231; // siUnknownInfoType
585 }
586 }
587
588
589 /*
590 * Sound input driver Status() routine
591 */
592
593 int16 SoundInStatus(uint32 pb, uint32 dce)
594 {
595 uint16 code = ReadMacInt16(pb + csCode);
596 D(bug("SoundInStatus %d\n", code));
597 if (code != 2)
598 return -231; // siUnknownInfoType
599
600 uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
601 uint32 selector = param[0];
602 D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
603 switch (selector) {
604 #if 0
605 case siDeviceName: {
606 const char *str = GetString(STR_SOUND_IN_NAME);
607 param[0] = 0;
608 memcpy((void *)param[1], str, strlen(str));
609 return noErr;
610 }
611
612 case siDeviceIcon: {
613 M68kRegisters r;
614 static const uint8 proc[] = {
615 0x55, 0x8f, // subq.l #2,sp
616 0xa9, 0x94, // CurResFile
617 0x42, 0x67, // clr.w -(sp)
618 0xa9, 0x98, // UseResFile
619 0x59, 0x8f, // subq.l #4,sp
620 0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp)
621 0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp)
622 0xa9, 0xa0, // GetResource
623 0x24, 0x5f, // move.l (sp)+,a2
624 0xa9, 0x98, // UseResFile
625 0x20, 0x0a, // move.l a2,d0
626 0x66, 0x04, // bne 1
627 0x70, 0x00, // moveq #0,d0
628 M68K_RTS >> 8, M68K_RTS & 0xff,
629 0x2f, 0x0a, //1 move.l a2,-(sp)
630 0xa9, 0x92, // DetachResource
631 0x20, 0x4a, // move.l a2,a0
632 0xa0, 0x4a, // HNoPurge
633 0x70, 0x01, // moveq #1,d0
634 M68K_RTS >> 8, M68K_RTS & 0xff
635 };
636 Execute68k(Host2MacAddr((uint8 *)proc), &r);
637 if (r.d[0]) {
638 param[0] = 4; // Length of returned data
639 param[1] = r.a[2]; // Handle to icon suite
640 return noErr;
641 } else
642 return -192; // resNotFound
643 }
644 #endif
645 default:
646 return -231; // siUnknownInfoType
647 }
648 }
649
650
651 /*
652 * Sound input driver Close() routine
653 */
654
655 int16 SoundInClose(uint32 pb, uint32 dce)
656 {
657 D(bug("SoundInClose\n"));
658 return noErr;
659 }