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