]> git.proxmox.com Git - mirror_qemu.git/blob - hw/sb16.c
Make audio violate POSIX less
[mirror_qemu.git] / hw / sb16.c
1 /*
2 * QEMU Soundblaster 16 emulation
3 *
4 * Copyright (c) 2003-2005 Vassili Karpov (malc)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include "hw.h"
25 #include "audiodev.h"
26 #include "audio/audio.h"
27 #include "isa.h"
28 #include "qemu-timer.h"
29
30 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
31
32 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
33
34 /* #define DEBUG */
35 /* #define DEBUG_SB16_MOST */
36
37 #ifdef DEBUG
38 #define ldebug(...) dolog (__VA_ARGS__)
39 #else
40 #define ldebug(...)
41 #endif
42
43 #define IO_READ_PROTO(name) \
44 uint32_t name (void *opaque, uint32_t nport)
45 #define IO_WRITE_PROTO(name) \
46 void name (void *opaque, uint32_t nport, uint32_t val)
47
48 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
49
50 static struct {
51 int ver_lo;
52 int ver_hi;
53 int irq;
54 int dma;
55 int hdma;
56 int port;
57 } conf = {5, 4, 5, 1, 5, 0x220};
58
59 typedef struct SB16State {
60 QEMUSoundCard card;
61 qemu_irq *pic;
62 int irq;
63 int dma;
64 int hdma;
65 int port;
66 int ver;
67
68 int in_index;
69 int out_data_len;
70 int fmt_stereo;
71 int fmt_signed;
72 int fmt_bits;
73 audfmt_e fmt;
74 int dma_auto;
75 int block_size;
76 int fifo;
77 int freq;
78 int time_const;
79 int speaker;
80 int needed_bytes;
81 int cmd;
82 int use_hdma;
83 int highspeed;
84 int can_write;
85
86 int v2x6;
87
88 uint8_t csp_param;
89 uint8_t csp_value;
90 uint8_t csp_mode;
91 uint8_t csp_regs[256];
92 uint8_t csp_index;
93 uint8_t csp_reg83[4];
94 int csp_reg83r;
95 int csp_reg83w;
96
97 uint8_t in2_data[10];
98 uint8_t out_data[50];
99 uint8_t test_reg;
100 uint8_t last_read_byte;
101 int nzero;
102
103 int left_till_irq;
104
105 int dma_running;
106 int bytes_per_second;
107 int align;
108 int audio_free;
109 SWVoiceOut *voice;
110
111 QEMUTimer *aux_ts;
112 /* mixer state */
113 int mixer_nreg;
114 uint8_t mixer_regs[256];
115 } SB16State;
116
117 static void SB_audio_callback (void *opaque, int free);
118
119 static int magic_of_irq (int irq)
120 {
121 switch (irq) {
122 case 5:
123 return 2;
124 case 7:
125 return 4;
126 case 9:
127 return 1;
128 case 10:
129 return 8;
130 default:
131 dolog ("bad irq %d\n", irq);
132 return 2;
133 }
134 }
135
136 static int irq_of_magic (int magic)
137 {
138 switch (magic) {
139 case 1:
140 return 9;
141 case 2:
142 return 5;
143 case 4:
144 return 7;
145 case 8:
146 return 10;
147 default:
148 dolog ("bad irq magic %d\n", magic);
149 return -1;
150 }
151 }
152
153 #if 0
154 static void log_dsp (SB16State *dsp)
155 {
156 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
157 dsp->fmt_stereo ? "Stereo" : "Mono",
158 dsp->fmt_signed ? "Signed" : "Unsigned",
159 dsp->fmt_bits,
160 dsp->dma_auto ? "Auto" : "Single",
161 dsp->block_size,
162 dsp->freq,
163 dsp->time_const,
164 dsp->speaker);
165 }
166 #endif
167
168 static void speaker (SB16State *s, int on)
169 {
170 s->speaker = on;
171 /* AUD_enable (s->voice, on); */
172 }
173
174 static void control (SB16State *s, int hold)
175 {
176 int dma = s->use_hdma ? s->hdma : s->dma;
177 s->dma_running = hold;
178
179 ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
180
181 if (hold) {
182 DMA_hold_DREQ (dma);
183 AUD_set_active_out (s->voice, 1);
184 }
185 else {
186 DMA_release_DREQ (dma);
187 AUD_set_active_out (s->voice, 0);
188 }
189 }
190
191 static void aux_timer (void *opaque)
192 {
193 SB16State *s = opaque;
194 s->can_write = 1;
195 qemu_irq_raise (s->pic[s->irq]);
196 }
197
198 #define DMA8_AUTO 1
199 #define DMA8_HIGH 2
200
201 static void continue_dma8 (SB16State *s)
202 {
203 if (s->freq > 0) {
204 struct audsettings as;
205
206 s->audio_free = 0;
207
208 as.freq = s->freq;
209 as.nchannels = 1 << s->fmt_stereo;
210 as.fmt = s->fmt;
211 as.endianness = 0;
212
213 s->voice = AUD_open_out (
214 &s->card,
215 s->voice,
216 "sb16",
217 s,
218 SB_audio_callback,
219 &as
220 );
221 }
222
223 control (s, 1);
224 }
225
226 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
227 {
228 s->fmt = AUD_FMT_U8;
229 s->use_hdma = 0;
230 s->fmt_bits = 8;
231 s->fmt_signed = 0;
232 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
233 if (-1 == s->time_const) {
234 if (s->freq <= 0)
235 s->freq = 11025;
236 }
237 else {
238 int tmp = (256 - s->time_const);
239 s->freq = (1000000 + (tmp / 2)) / tmp;
240 }
241
242 if (dma_len != -1) {
243 s->block_size = dma_len << s->fmt_stereo;
244 }
245 else {
246 /* This is apparently the only way to make both Act1/PL
247 and SecondReality/FC work
248
249 Act1 sets block size via command 0x48 and it's an odd number
250 SR does the same with even number
251 Both use stereo, and Creatives own documentation states that
252 0x48 sets block size in bytes less one.. go figure */
253 s->block_size &= ~s->fmt_stereo;
254 }
255
256 s->freq >>= s->fmt_stereo;
257 s->left_till_irq = s->block_size;
258 s->bytes_per_second = (s->freq << s->fmt_stereo);
259 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
260 s->dma_auto = (mask & DMA8_AUTO) != 0;
261 s->align = (1 << s->fmt_stereo) - 1;
262
263 if (s->block_size & s->align) {
264 dolog ("warning: misaligned block size %d, alignment %d\n",
265 s->block_size, s->align + 1);
266 }
267
268 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
269 "dma %d, auto %d, fifo %d, high %d\n",
270 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
271 s->block_size, s->dma_auto, s->fifo, s->highspeed);
272
273 continue_dma8 (s);
274 speaker (s, 1);
275 }
276
277 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
278 {
279 s->use_hdma = cmd < 0xc0;
280 s->fifo = (cmd >> 1) & 1;
281 s->dma_auto = (cmd >> 2) & 1;
282 s->fmt_signed = (d0 >> 4) & 1;
283 s->fmt_stereo = (d0 >> 5) & 1;
284
285 switch (cmd >> 4) {
286 case 11:
287 s->fmt_bits = 16;
288 break;
289
290 case 12:
291 s->fmt_bits = 8;
292 break;
293 }
294
295 if (-1 != s->time_const) {
296 #if 1
297 int tmp = 256 - s->time_const;
298 s->freq = (1000000 + (tmp / 2)) / tmp;
299 #else
300 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
301 s->freq = 1000000 / ((255 - s->time_const));
302 #endif
303 s->time_const = -1;
304 }
305
306 s->block_size = dma_len + 1;
307 s->block_size <<= (s->fmt_bits == 16);
308 if (!s->dma_auto) {
309 /* It is clear that for DOOM and auto-init this value
310 shouldn't take stereo into account, while Miles Sound Systems
311 setsound.exe with single transfer mode wouldn't work without it
312 wonders of SB16 yet again */
313 s->block_size <<= s->fmt_stereo;
314 }
315
316 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
317 "dma %d, auto %d, fifo %d, high %d\n",
318 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
319 s->block_size, s->dma_auto, s->fifo, s->highspeed);
320
321 if (16 == s->fmt_bits) {
322 if (s->fmt_signed) {
323 s->fmt = AUD_FMT_S16;
324 }
325 else {
326 s->fmt = AUD_FMT_U16;
327 }
328 }
329 else {
330 if (s->fmt_signed) {
331 s->fmt = AUD_FMT_S8;
332 }
333 else {
334 s->fmt = AUD_FMT_U8;
335 }
336 }
337
338 s->left_till_irq = s->block_size;
339
340 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
341 s->highspeed = 0;
342 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
343 if (s->block_size & s->align) {
344 dolog ("warning: misaligned block size %d, alignment %d\n",
345 s->block_size, s->align + 1);
346 }
347
348 if (s->freq) {
349 struct audsettings as;
350
351 s->audio_free = 0;
352
353 as.freq = s->freq;
354 as.nchannels = 1 << s->fmt_stereo;
355 as.fmt = s->fmt;
356 as.endianness = 0;
357
358 s->voice = AUD_open_out (
359 &s->card,
360 s->voice,
361 "sb16",
362 s,
363 SB_audio_callback,
364 &as
365 );
366 }
367
368 control (s, 1);
369 speaker (s, 1);
370 }
371
372 static inline void dsp_out_data (SB16State *s, uint8_t val)
373 {
374 ldebug ("outdata %#x\n", val);
375 if ((size_t) s->out_data_len < sizeof (s->out_data)) {
376 s->out_data[s->out_data_len++] = val;
377 }
378 }
379
380 static inline uint8_t dsp_get_data (SB16State *s)
381 {
382 if (s->in_index) {
383 return s->in2_data[--s->in_index];
384 }
385 else {
386 dolog ("buffer underflow\n");
387 return 0;
388 }
389 }
390
391 static void command (SB16State *s, uint8_t cmd)
392 {
393 ldebug ("command %#x\n", cmd);
394
395 if (cmd > 0xaf && cmd < 0xd0) {
396 if (cmd & 8) {
397 dolog ("ADC not yet supported (command %#x)\n", cmd);
398 }
399
400 switch (cmd >> 4) {
401 case 11:
402 case 12:
403 break;
404 default:
405 dolog ("%#x wrong bits\n", cmd);
406 }
407 s->needed_bytes = 3;
408 }
409 else {
410 s->needed_bytes = 0;
411
412 switch (cmd) {
413 case 0x03:
414 dsp_out_data (s, 0x10); /* s->csp_param); */
415 goto warn;
416
417 case 0x04:
418 s->needed_bytes = 1;
419 goto warn;
420
421 case 0x05:
422 s->needed_bytes = 2;
423 goto warn;
424
425 case 0x08:
426 /* __asm__ ("int3"); */
427 goto warn;
428
429 case 0x0e:
430 s->needed_bytes = 2;
431 goto warn;
432
433 case 0x09:
434 dsp_out_data (s, 0xf8);
435 goto warn;
436
437 case 0x0f:
438 s->needed_bytes = 1;
439 goto warn;
440
441 case 0x10:
442 s->needed_bytes = 1;
443 goto warn;
444
445 case 0x14:
446 s->needed_bytes = 2;
447 s->block_size = 0;
448 break;
449
450 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
451 dma_cmd8 (s, DMA8_AUTO, -1);
452 break;
453
454 case 0x20: /* Direct ADC, Juice/PL */
455 dsp_out_data (s, 0xff);
456 goto warn;
457
458 case 0x35:
459 dolog ("0x35 - MIDI command not implemented\n");
460 break;
461
462 case 0x40:
463 s->freq = -1;
464 s->time_const = -1;
465 s->needed_bytes = 1;
466 break;
467
468 case 0x41:
469 s->freq = -1;
470 s->time_const = -1;
471 s->needed_bytes = 2;
472 break;
473
474 case 0x42:
475 s->freq = -1;
476 s->time_const = -1;
477 s->needed_bytes = 2;
478 goto warn;
479
480 case 0x45:
481 dsp_out_data (s, 0xaa);
482 goto warn;
483
484 case 0x47: /* Continue Auto-Initialize DMA 16bit */
485 break;
486
487 case 0x48:
488 s->needed_bytes = 2;
489 break;
490
491 case 0x74:
492 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
493 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
494 break;
495
496 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
497 s->needed_bytes = 2;
498 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
499 break;
500
501 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
502 s->needed_bytes = 2;
503 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
504 break;
505
506 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
507 s->needed_bytes = 2;
508 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
509 break;
510
511 case 0x7d:
512 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
513 dolog ("not implemented\n");
514 break;
515
516 case 0x7f:
517 dolog (
518 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
519 );
520 dolog ("not implemented\n");
521 break;
522
523 case 0x80:
524 s->needed_bytes = 2;
525 break;
526
527 case 0x90:
528 case 0x91:
529 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
530 break;
531
532 case 0xd0: /* halt DMA operation. 8bit */
533 control (s, 0);
534 break;
535
536 case 0xd1: /* speaker on */
537 speaker (s, 1);
538 break;
539
540 case 0xd3: /* speaker off */
541 speaker (s, 0);
542 break;
543
544 case 0xd4: /* continue DMA operation. 8bit */
545 /* KQ6 (or maybe Sierras audblst.drv in general) resets
546 the frequency between halt/continue */
547 continue_dma8 (s);
548 break;
549
550 case 0xd5: /* halt DMA operation. 16bit */
551 control (s, 0);
552 break;
553
554 case 0xd6: /* continue DMA operation. 16bit */
555 control (s, 1);
556 break;
557
558 case 0xd9: /* exit auto-init DMA after this block. 16bit */
559 s->dma_auto = 0;
560 break;
561
562 case 0xda: /* exit auto-init DMA after this block. 8bit */
563 s->dma_auto = 0;
564 break;
565
566 case 0xe0: /* DSP identification */
567 s->needed_bytes = 1;
568 break;
569
570 case 0xe1:
571 dsp_out_data (s, s->ver & 0xff);
572 dsp_out_data (s, s->ver >> 8);
573 break;
574
575 case 0xe2:
576 s->needed_bytes = 1;
577 goto warn;
578
579 case 0xe3:
580 {
581 int i;
582 for (i = sizeof (e3) - 1; i >= 0; --i)
583 dsp_out_data (s, e3[i]);
584 }
585 break;
586
587 case 0xe4: /* write test reg */
588 s->needed_bytes = 1;
589 break;
590
591 case 0xe7:
592 dolog ("Attempt to probe for ESS (0xe7)?\n");
593 break;
594
595 case 0xe8: /* read test reg */
596 dsp_out_data (s, s->test_reg);
597 break;
598
599 case 0xf2:
600 case 0xf3:
601 dsp_out_data (s, 0xaa);
602 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
603 qemu_irq_raise (s->pic[s->irq]);
604 break;
605
606 case 0xf9:
607 s->needed_bytes = 1;
608 goto warn;
609
610 case 0xfa:
611 dsp_out_data (s, 0);
612 goto warn;
613
614 case 0xfc: /* FIXME */
615 dsp_out_data (s, 0);
616 goto warn;
617
618 default:
619 dolog ("Unrecognized command %#x\n", cmd);
620 break;
621 }
622 }
623
624 if (!s->needed_bytes) {
625 ldebug ("\n");
626 }
627
628 exit:
629 if (!s->needed_bytes) {
630 s->cmd = -1;
631 }
632 else {
633 s->cmd = cmd;
634 }
635 return;
636
637 warn:
638 dolog ("warning: command %#x,%d is not truly understood yet\n",
639 cmd, s->needed_bytes);
640 goto exit;
641
642 }
643
644 static uint16_t dsp_get_lohi (SB16State *s)
645 {
646 uint8_t hi = dsp_get_data (s);
647 uint8_t lo = dsp_get_data (s);
648 return (hi << 8) | lo;
649 }
650
651 static uint16_t dsp_get_hilo (SB16State *s)
652 {
653 uint8_t lo = dsp_get_data (s);
654 uint8_t hi = dsp_get_data (s);
655 return (hi << 8) | lo;
656 }
657
658 static void complete (SB16State *s)
659 {
660 int d0, d1, d2;
661 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
662 s->cmd, s->in_index, s->needed_bytes);
663
664 if (s->cmd > 0xaf && s->cmd < 0xd0) {
665 d2 = dsp_get_data (s);
666 d1 = dsp_get_data (s);
667 d0 = dsp_get_data (s);
668
669 if (s->cmd & 8) {
670 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
671 s->cmd, d0, d1, d2);
672 }
673 else {
674 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
675 s->cmd, d0, d1, d2);
676 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
677 }
678 }
679 else {
680 switch (s->cmd) {
681 case 0x04:
682 s->csp_mode = dsp_get_data (s);
683 s->csp_reg83r = 0;
684 s->csp_reg83w = 0;
685 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
686 break;
687
688 case 0x05:
689 s->csp_param = dsp_get_data (s);
690 s->csp_value = dsp_get_data (s);
691 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
692 s->csp_param,
693 s->csp_value);
694 break;
695
696 case 0x0e:
697 d0 = dsp_get_data (s);
698 d1 = dsp_get_data (s);
699 ldebug ("write CSP register %d <- %#x\n", d1, d0);
700 if (d1 == 0x83) {
701 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
702 s->csp_reg83[s->csp_reg83r % 4] = d0;
703 s->csp_reg83r += 1;
704 }
705 else {
706 s->csp_regs[d1] = d0;
707 }
708 break;
709
710 case 0x0f:
711 d0 = dsp_get_data (s);
712 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
713 d0, s->csp_regs[d0], s->csp_mode);
714 if (d0 == 0x83) {
715 ldebug ("0x83[%d] -> %#x\n",
716 s->csp_reg83w,
717 s->csp_reg83[s->csp_reg83w % 4]);
718 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
719 s->csp_reg83w += 1;
720 }
721 else {
722 dsp_out_data (s, s->csp_regs[d0]);
723 }
724 break;
725
726 case 0x10:
727 d0 = dsp_get_data (s);
728 dolog ("cmd 0x10 d0=%#x\n", d0);
729 break;
730
731 case 0x14:
732 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
733 break;
734
735 case 0x40:
736 s->time_const = dsp_get_data (s);
737 ldebug ("set time const %d\n", s->time_const);
738 break;
739
740 case 0x42: /* FT2 sets output freq with this, go figure */
741 #if 0
742 dolog ("cmd 0x42 might not do what it think it should\n");
743 #endif
744 case 0x41:
745 s->freq = dsp_get_hilo (s);
746 ldebug ("set freq %d\n", s->freq);
747 break;
748
749 case 0x48:
750 s->block_size = dsp_get_lohi (s) + 1;
751 ldebug ("set dma block len %d\n", s->block_size);
752 break;
753
754 case 0x74:
755 case 0x75:
756 case 0x76:
757 case 0x77:
758 /* ADPCM stuff, ignore */
759 break;
760
761 case 0x80:
762 {
763 int freq, samples, bytes;
764 int64_t ticks;
765
766 freq = s->freq > 0 ? s->freq : 11025;
767 samples = dsp_get_lohi (s) + 1;
768 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
769 ticks = (bytes * ticks_per_sec) / freq;
770 if (ticks < ticks_per_sec / 1024) {
771 qemu_irq_raise (s->pic[s->irq]);
772 }
773 else {
774 if (s->aux_ts) {
775 qemu_mod_timer (
776 s->aux_ts,
777 qemu_get_clock (vm_clock) + ticks
778 );
779 }
780 }
781 ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
782 }
783 break;
784
785 case 0xe0:
786 d0 = dsp_get_data (s);
787 s->out_data_len = 0;
788 ldebug ("E0 data = %#x\n", d0);
789 dsp_out_data (s, ~d0);
790 break;
791
792 case 0xe2:
793 d0 = dsp_get_data (s);
794 ldebug ("E2 = %#x\n", d0);
795 break;
796
797 case 0xe4:
798 s->test_reg = dsp_get_data (s);
799 break;
800
801 case 0xf9:
802 d0 = dsp_get_data (s);
803 ldebug ("command 0xf9 with %#x\n", d0);
804 switch (d0) {
805 case 0x0e:
806 dsp_out_data (s, 0xff);
807 break;
808
809 case 0x0f:
810 dsp_out_data (s, 0x07);
811 break;
812
813 case 0x37:
814 dsp_out_data (s, 0x38);
815 break;
816
817 default:
818 dsp_out_data (s, 0x00);
819 break;
820 }
821 break;
822
823 default:
824 dolog ("complete: unrecognized command %#x\n", s->cmd);
825 return;
826 }
827 }
828
829 ldebug ("\n");
830 s->cmd = -1;
831 return;
832 }
833
834 static void legacy_reset (SB16State *s)
835 {
836 struct audsettings as;
837
838 s->freq = 11025;
839 s->fmt_signed = 0;
840 s->fmt_bits = 8;
841 s->fmt_stereo = 0;
842
843 as.freq = s->freq;
844 as.nchannels = 1;
845 as.fmt = AUD_FMT_U8;
846 as.endianness = 0;
847
848 s->voice = AUD_open_out (
849 &s->card,
850 s->voice,
851 "sb16",
852 s,
853 SB_audio_callback,
854 &as
855 );
856
857 /* Not sure about that... */
858 /* AUD_set_active_out (s->voice, 1); */
859 }
860
861 static void reset (SB16State *s)
862 {
863 qemu_irq_lower (s->pic[s->irq]);
864 if (s->dma_auto) {
865 qemu_irq_raise (s->pic[s->irq]);
866 qemu_irq_lower (s->pic[s->irq]);
867 }
868
869 s->mixer_regs[0x82] = 0;
870 s->dma_auto = 0;
871 s->in_index = 0;
872 s->out_data_len = 0;
873 s->left_till_irq = 0;
874 s->needed_bytes = 0;
875 s->block_size = -1;
876 s->nzero = 0;
877 s->highspeed = 0;
878 s->v2x6 = 0;
879 s->cmd = -1;
880
881 dsp_out_data(s, 0xaa);
882 speaker (s, 0);
883 control (s, 0);
884 legacy_reset (s);
885 }
886
887 static IO_WRITE_PROTO (dsp_write)
888 {
889 SB16State *s = opaque;
890 int iport;
891
892 iport = nport - s->port;
893
894 ldebug ("write %#x <- %#x\n", nport, val);
895 switch (iport) {
896 case 0x06:
897 switch (val) {
898 case 0x00:
899 if (s->v2x6 == 1) {
900 if (0 && s->highspeed) {
901 s->highspeed = 0;
902 qemu_irq_lower (s->pic[s->irq]);
903 control (s, 0);
904 }
905 else {
906 reset (s);
907 }
908 }
909 s->v2x6 = 0;
910 break;
911
912 case 0x01:
913 case 0x03: /* FreeBSD kludge */
914 s->v2x6 = 1;
915 break;
916
917 case 0xc6:
918 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
919 break;
920
921 case 0xb8: /* Panic */
922 reset (s);
923 break;
924
925 case 0x39:
926 dsp_out_data (s, 0x38);
927 reset (s);
928 s->v2x6 = 0x39;
929 break;
930
931 default:
932 s->v2x6 = val;
933 break;
934 }
935 break;
936
937 case 0x0c: /* write data or command | write status */
938 /* if (s->highspeed) */
939 /* break; */
940
941 if (0 == s->needed_bytes) {
942 command (s, val);
943 #if 0
944 if (0 == s->needed_bytes) {
945 log_dsp (s);
946 }
947 #endif
948 }
949 else {
950 if (s->in_index == sizeof (s->in2_data)) {
951 dolog ("in data overrun\n");
952 }
953 else {
954 s->in2_data[s->in_index++] = val;
955 if (s->in_index == s->needed_bytes) {
956 s->needed_bytes = 0;
957 complete (s);
958 #if 0
959 log_dsp (s);
960 #endif
961 }
962 }
963 }
964 break;
965
966 default:
967 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
968 break;
969 }
970 }
971
972 static IO_READ_PROTO (dsp_read)
973 {
974 SB16State *s = opaque;
975 int iport, retval, ack = 0;
976
977 iport = nport - s->port;
978
979 switch (iport) {
980 case 0x06: /* reset */
981 retval = 0xff;
982 break;
983
984 case 0x0a: /* read data */
985 if (s->out_data_len) {
986 retval = s->out_data[--s->out_data_len];
987 s->last_read_byte = retval;
988 }
989 else {
990 if (s->cmd != -1) {
991 dolog ("empty output buffer for command %#x\n",
992 s->cmd);
993 }
994 retval = s->last_read_byte;
995 /* goto error; */
996 }
997 break;
998
999 case 0x0c: /* 0 can write */
1000 retval = s->can_write ? 0 : 0x80;
1001 break;
1002
1003 case 0x0d: /* timer interrupt clear */
1004 /* dolog ("timer interrupt clear\n"); */
1005 retval = 0;
1006 break;
1007
1008 case 0x0e: /* data available status | irq 8 ack */
1009 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1010 if (s->mixer_regs[0x82] & 1) {
1011 ack = 1;
1012 s->mixer_regs[0x82] &= 1;
1013 qemu_irq_lower (s->pic[s->irq]);
1014 }
1015 break;
1016
1017 case 0x0f: /* irq 16 ack */
1018 retval = 0xff;
1019 if (s->mixer_regs[0x82] & 2) {
1020 ack = 1;
1021 s->mixer_regs[0x82] &= 2;
1022 qemu_irq_lower (s->pic[s->irq]);
1023 }
1024 break;
1025
1026 default:
1027 goto error;
1028 }
1029
1030 if (!ack) {
1031 ldebug ("read %#x -> %#x\n", nport, retval);
1032 }
1033
1034 return retval;
1035
1036 error:
1037 dolog ("warning: dsp_read %#x error\n", nport);
1038 return 0xff;
1039 }
1040
1041 static void reset_mixer (SB16State *s)
1042 {
1043 int i;
1044
1045 memset (s->mixer_regs, 0xff, 0x7f);
1046 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1047
1048 s->mixer_regs[0x02] = 4; /* master volume 3bits */
1049 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
1050 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
1051 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1052
1053 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1054 s->mixer_regs[0x0c] = 0;
1055
1056 /* d5=output filt, d1=stereo switch */
1057 s->mixer_regs[0x0e] = 0;
1058
1059 /* voice volume L d5,d7, R d1,d3 */
1060 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1061 /* master ... */
1062 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1063 /* MIDI ... */
1064 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1065
1066 for (i = 0x30; i < 0x48; i++) {
1067 s->mixer_regs[i] = 0x20;
1068 }
1069 }
1070
1071 static IO_WRITE_PROTO(mixer_write_indexb)
1072 {
1073 SB16State *s = opaque;
1074 (void) nport;
1075 s->mixer_nreg = val;
1076 }
1077
1078 static IO_WRITE_PROTO(mixer_write_datab)
1079 {
1080 SB16State *s = opaque;
1081
1082 (void) nport;
1083 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1084
1085 switch (s->mixer_nreg) {
1086 case 0x00:
1087 reset_mixer (s);
1088 break;
1089
1090 case 0x80:
1091 {
1092 int irq = irq_of_magic (val);
1093 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1094 if (irq > 0) {
1095 s->irq = irq;
1096 }
1097 }
1098 break;
1099
1100 case 0x81:
1101 {
1102 int dma, hdma;
1103
1104 dma = lsbindex (val & 0xf);
1105 hdma = lsbindex (val & 0xf0);
1106 if (dma != s->dma || hdma != s->hdma) {
1107 dolog (
1108 "attempt to change DMA "
1109 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1110 dma, s->dma, hdma, s->hdma, val);
1111 }
1112 #if 0
1113 s->dma = dma;
1114 s->hdma = hdma;
1115 #endif
1116 }
1117 break;
1118
1119 case 0x82:
1120 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1121 val);
1122 return;
1123
1124 default:
1125 if (s->mixer_nreg >= 0x80) {
1126 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1127 }
1128 break;
1129 }
1130
1131 s->mixer_regs[s->mixer_nreg] = val;
1132 }
1133
1134 static IO_WRITE_PROTO(mixer_write_indexw)
1135 {
1136 mixer_write_indexb (opaque, nport, val & 0xff);
1137 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1138 }
1139
1140 static IO_READ_PROTO(mixer_read)
1141 {
1142 SB16State *s = opaque;
1143
1144 (void) nport;
1145 #ifndef DEBUG_SB16_MOST
1146 if (s->mixer_nreg != 0x82) {
1147 ldebug ("mixer_read[%#x] -> %#x\n",
1148 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1149 }
1150 #else
1151 ldebug ("mixer_read[%#x] -> %#x\n",
1152 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1153 #endif
1154 return s->mixer_regs[s->mixer_nreg];
1155 }
1156
1157 static int write_audio (SB16State *s, int nchan, int dma_pos,
1158 int dma_len, int len)
1159 {
1160 int temp, net;
1161 uint8_t tmpbuf[4096];
1162
1163 temp = len;
1164 net = 0;
1165
1166 while (temp) {
1167 int left = dma_len - dma_pos;
1168 int copied;
1169 size_t to_copy;
1170
1171 to_copy = audio_MIN (temp, left);
1172 if (to_copy > sizeof (tmpbuf)) {
1173 to_copy = sizeof (tmpbuf);
1174 }
1175
1176 copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1177 copied = AUD_write (s->voice, tmpbuf, copied);
1178
1179 temp -= copied;
1180 dma_pos = (dma_pos + copied) % dma_len;
1181 net += copied;
1182
1183 if (!copied) {
1184 break;
1185 }
1186 }
1187
1188 return net;
1189 }
1190
1191 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1192 {
1193 SB16State *s = opaque;
1194 int till, copy, written, free;
1195
1196 if (s->block_size <= 0) {
1197 dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1198 s->block_size, nchan, dma_pos, dma_len);
1199 return dma_pos;
1200 }
1201
1202 if (s->left_till_irq < 0) {
1203 s->left_till_irq = s->block_size;
1204 }
1205
1206 if (s->voice) {
1207 free = s->audio_free & ~s->align;
1208 if ((free <= 0) || !dma_len) {
1209 return dma_pos;
1210 }
1211 }
1212 else {
1213 free = dma_len;
1214 }
1215
1216 copy = free;
1217 till = s->left_till_irq;
1218
1219 #ifdef DEBUG_SB16_MOST
1220 dolog ("pos:%06d %d till:%d len:%d\n",
1221 dma_pos, free, till, dma_len);
1222 #endif
1223
1224 if (till <= copy) {
1225 if (0 == s->dma_auto) {
1226 copy = till;
1227 }
1228 }
1229
1230 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1231 dma_pos = (dma_pos + written) % dma_len;
1232 s->left_till_irq -= written;
1233
1234 if (s->left_till_irq <= 0) {
1235 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1236 qemu_irq_raise (s->pic[s->irq]);
1237 if (0 == s->dma_auto) {
1238 control (s, 0);
1239 speaker (s, 0);
1240 }
1241 }
1242
1243 #ifdef DEBUG_SB16_MOST
1244 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1245 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1246 s->block_size);
1247 #endif
1248
1249 while (s->left_till_irq <= 0) {
1250 s->left_till_irq = s->block_size + s->left_till_irq;
1251 }
1252
1253 return dma_pos;
1254 }
1255
1256 static void SB_audio_callback (void *opaque, int free)
1257 {
1258 SB16State *s = opaque;
1259 s->audio_free = free;
1260 }
1261
1262 static void SB_save (QEMUFile *f, void *opaque)
1263 {
1264 SB16State *s = opaque;
1265
1266 qemu_put_be32 (f, s->irq);
1267 qemu_put_be32 (f, s->dma);
1268 qemu_put_be32 (f, s->hdma);
1269 qemu_put_be32 (f, s->port);
1270 qemu_put_be32 (f, s->ver);
1271 qemu_put_be32 (f, s->in_index);
1272 qemu_put_be32 (f, s->out_data_len);
1273 qemu_put_be32 (f, s->fmt_stereo);
1274 qemu_put_be32 (f, s->fmt_signed);
1275 qemu_put_be32 (f, s->fmt_bits);
1276 qemu_put_be32s (f, &s->fmt);
1277 qemu_put_be32 (f, s->dma_auto);
1278 qemu_put_be32 (f, s->block_size);
1279 qemu_put_be32 (f, s->fifo);
1280 qemu_put_be32 (f, s->freq);
1281 qemu_put_be32 (f, s->time_const);
1282 qemu_put_be32 (f, s->speaker);
1283 qemu_put_be32 (f, s->needed_bytes);
1284 qemu_put_be32 (f, s->cmd);
1285 qemu_put_be32 (f, s->use_hdma);
1286 qemu_put_be32 (f, s->highspeed);
1287 qemu_put_be32 (f, s->can_write);
1288 qemu_put_be32 (f, s->v2x6);
1289
1290 qemu_put_8s (f, &s->csp_param);
1291 qemu_put_8s (f, &s->csp_value);
1292 qemu_put_8s (f, &s->csp_mode);
1293 qemu_put_8s (f, &s->csp_param);
1294 qemu_put_buffer (f, s->csp_regs, 256);
1295 qemu_put_8s (f, &s->csp_index);
1296 qemu_put_buffer (f, s->csp_reg83, 4);
1297 qemu_put_be32 (f, s->csp_reg83r);
1298 qemu_put_be32 (f, s->csp_reg83w);
1299
1300 qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1301 qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1302 qemu_put_8s (f, &s->test_reg);
1303 qemu_put_8s (f, &s->last_read_byte);
1304
1305 qemu_put_be32 (f, s->nzero);
1306 qemu_put_be32 (f, s->left_till_irq);
1307 qemu_put_be32 (f, s->dma_running);
1308 qemu_put_be32 (f, s->bytes_per_second);
1309 qemu_put_be32 (f, s->align);
1310
1311 qemu_put_be32 (f, s->mixer_nreg);
1312 qemu_put_buffer (f, s->mixer_regs, 256);
1313 }
1314
1315 static int SB_load (QEMUFile *f, void *opaque, int version_id)
1316 {
1317 SB16State *s = opaque;
1318
1319 if (version_id != 1) {
1320 return -EINVAL;
1321 }
1322
1323 s->irq=qemu_get_be32 (f);
1324 s->dma=qemu_get_be32 (f);
1325 s->hdma=qemu_get_be32 (f);
1326 s->port=qemu_get_be32 (f);
1327 s->ver=qemu_get_be32 (f);
1328 s->in_index=qemu_get_be32 (f);
1329 s->out_data_len=qemu_get_be32 (f);
1330 s->fmt_stereo=qemu_get_be32 (f);
1331 s->fmt_signed=qemu_get_be32 (f);
1332 s->fmt_bits=qemu_get_be32 (f);
1333 qemu_get_be32s (f, &s->fmt);
1334 s->dma_auto=qemu_get_be32 (f);
1335 s->block_size=qemu_get_be32 (f);
1336 s->fifo=qemu_get_be32 (f);
1337 s->freq=qemu_get_be32 (f);
1338 s->time_const=qemu_get_be32 (f);
1339 s->speaker=qemu_get_be32 (f);
1340 s->needed_bytes=qemu_get_be32 (f);
1341 s->cmd=qemu_get_be32 (f);
1342 s->use_hdma=qemu_get_be32 (f);
1343 s->highspeed=qemu_get_be32 (f);
1344 s->can_write=qemu_get_be32 (f);
1345 s->v2x6=qemu_get_be32 (f);
1346
1347 qemu_get_8s (f, &s->csp_param);
1348 qemu_get_8s (f, &s->csp_value);
1349 qemu_get_8s (f, &s->csp_mode);
1350 qemu_get_8s (f, &s->csp_param);
1351 qemu_get_buffer (f, s->csp_regs, 256);
1352 qemu_get_8s (f, &s->csp_index);
1353 qemu_get_buffer (f, s->csp_reg83, 4);
1354 s->csp_reg83r=qemu_get_be32 (f);
1355 s->csp_reg83w=qemu_get_be32 (f);
1356
1357 qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1358 qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1359 qemu_get_8s (f, &s->test_reg);
1360 qemu_get_8s (f, &s->last_read_byte);
1361
1362 s->nzero=qemu_get_be32 (f);
1363 s->left_till_irq=qemu_get_be32 (f);
1364 s->dma_running=qemu_get_be32 (f);
1365 s->bytes_per_second=qemu_get_be32 (f);
1366 s->align=qemu_get_be32 (f);
1367
1368 s->mixer_nreg=qemu_get_be32 (f);
1369 qemu_get_buffer (f, s->mixer_regs, 256);
1370
1371 if (s->voice) {
1372 AUD_close_out (&s->card, s->voice);
1373 s->voice = NULL;
1374 }
1375
1376 if (s->dma_running) {
1377 if (s->freq) {
1378 struct audsettings as;
1379
1380 s->audio_free = 0;
1381
1382 as.freq = s->freq;
1383 as.nchannels = 1 << s->fmt_stereo;
1384 as.fmt = s->fmt;
1385 as.endianness = 0;
1386
1387 s->voice = AUD_open_out (
1388 &s->card,
1389 s->voice,
1390 "sb16",
1391 s,
1392 SB_audio_callback,
1393 &as
1394 );
1395 }
1396
1397 control (s, 1);
1398 speaker (s, s->speaker);
1399 }
1400 return 0;
1401 }
1402
1403 int SB16_init (AudioState *audio, qemu_irq *pic)
1404 {
1405 SB16State *s;
1406 int i;
1407 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1408 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1409
1410 if (!audio) {
1411 dolog ("No audio state\n");
1412 return -1;
1413 }
1414
1415 s = qemu_mallocz (sizeof (*s));
1416 if (!s) {
1417 dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
1418 sizeof (*s));
1419 return -1;
1420 }
1421
1422 s->cmd = -1;
1423 s->pic = pic;
1424 s->irq = conf.irq;
1425 s->dma = conf.dma;
1426 s->hdma = conf.hdma;
1427 s->port = conf.port;
1428 s->ver = conf.ver_lo | (conf.ver_hi << 8);
1429
1430 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1431 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1432 s->mixer_regs[0x82] = 2 << 5;
1433
1434 s->csp_regs[5] = 1;
1435 s->csp_regs[9] = 0xf8;
1436
1437 reset_mixer (s);
1438 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1439 if (!s->aux_ts) {
1440 dolog ("warning: Could not create auxiliary timer\n");
1441 }
1442
1443 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1444 register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1445 }
1446
1447 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1448 register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1449 }
1450
1451 register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1452 register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1453 register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1454 register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1455
1456 DMA_register_channel (s->hdma, SB_read_DMA, s);
1457 DMA_register_channel (s->dma, SB_read_DMA, s);
1458 s->can_write = 1;
1459
1460 register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1461 AUD_register_card (audio, "sb16", &s->card);
1462 return 0;
1463 }