hw/riscv: Move sifive_u_otp model to hw/misc
[qemu/ar7.git] / hw / audio / sb16.c
blob2d9e50f99b5d4817b7f769475fa9f20851611fb3
1 /*
2 * QEMU Soundblaster 16 emulation
4 * Copyright (c) 2003-2005 Vassili Karpov (malc)
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
25 #include "qemu/osdep.h"
26 #include "hw/audio/soundhw.h"
27 #include "audio/audio.h"
28 #include "hw/irq.h"
29 #include "hw/isa/isa.h"
30 #include "hw/qdev-properties.h"
31 #include "migration/vmstate.h"
32 #include "qemu/timer.h"
33 #include "qemu/host-utils.h"
34 #include "qemu/log.h"
35 #include "qemu/module.h"
36 #include "qapi/error.h"
38 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
40 /* #define DEBUG */
41 /* #define DEBUG_SB16_MOST */
43 #ifdef DEBUG
44 #define ldebug(...) dolog (__VA_ARGS__)
45 #else
46 #define ldebug(...)
47 #endif
49 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
51 #define TYPE_SB16 "sb16"
52 #define SB16(obj) OBJECT_CHECK (SB16State, (obj), TYPE_SB16)
54 typedef struct SB16State {
55 ISADevice parent_obj;
57 QEMUSoundCard card;
58 qemu_irq pic;
59 uint32_t irq;
60 uint32_t dma;
61 uint32_t hdma;
62 uint32_t port;
63 uint32_t ver;
64 IsaDma *isa_dma;
65 IsaDma *isa_hdma;
67 int in_index;
68 int out_data_len;
69 int fmt_stereo;
70 int fmt_signed;
71 int fmt_bits;
72 AudioFormat fmt;
73 int dma_auto;
74 int block_size;
75 int fifo;
76 int freq;
77 int time_const;
78 int speaker;
79 int needed_bytes;
80 int cmd;
81 int use_hdma;
82 int highspeed;
83 int can_write;
85 int v2x6;
87 uint8_t csp_param;
88 uint8_t csp_value;
89 uint8_t csp_mode;
90 uint8_t csp_regs[256];
91 uint8_t csp_index;
92 uint8_t csp_reg83[4];
93 int csp_reg83r;
94 int csp_reg83w;
96 uint8_t in2_data[10];
97 uint8_t out_data[50];
98 uint8_t test_reg;
99 uint8_t last_read_byte;
100 int nzero;
102 int left_till_irq;
104 int dma_running;
105 int bytes_per_second;
106 int align;
107 int audio_free;
108 SWVoiceOut *voice;
110 QEMUTimer *aux_ts;
111 /* mixer state */
112 int mixer_nreg;
113 uint8_t mixer_regs[256];
114 PortioList portio_list;
115 } SB16State;
117 static void SB_audio_callback (void *opaque, int free);
119 static int magic_of_irq (int irq)
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 qemu_log_mask(LOG_GUEST_ERROR, "bad irq %d\n", irq);
132 return 2;
136 static int irq_of_magic (int magic)
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 qemu_log_mask(LOG_GUEST_ERROR, "bad irq magic %d\n", magic);
149 return -1;
153 #if 0
154 static void log_dsp (SB16State *dsp)
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);
166 #endif
168 static void speaker (SB16State *s, int on)
170 s->speaker = on;
171 /* AUD_enable (s->voice, on); */
174 static void control (SB16State *s, int hold)
176 int dma = s->use_hdma ? s->hdma : s->dma;
177 IsaDma *isa_dma = s->use_hdma ? s->isa_hdma : s->isa_dma;
178 IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
179 s->dma_running = hold;
181 ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
183 if (hold) {
184 k->hold_DREQ(isa_dma, dma);
185 AUD_set_active_out (s->voice, 1);
187 else {
188 k->release_DREQ(isa_dma, dma);
189 AUD_set_active_out (s->voice, 0);
193 static void aux_timer (void *opaque)
195 SB16State *s = opaque;
196 s->can_write = 1;
197 qemu_irq_raise (s->pic);
200 #define DMA8_AUTO 1
201 #define DMA8_HIGH 2
203 static void continue_dma8 (SB16State *s)
205 if (s->freq > 0) {
206 struct audsettings as;
208 s->audio_free = 0;
210 as.freq = s->freq;
211 as.nchannels = 1 << s->fmt_stereo;
212 as.fmt = s->fmt;
213 as.endianness = 0;
215 s->voice = AUD_open_out (
216 &s->card,
217 s->voice,
218 "sb16",
220 SB_audio_callback,
225 control (s, 1);
228 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
230 s->fmt = AUDIO_FORMAT_U8;
231 s->use_hdma = 0;
232 s->fmt_bits = 8;
233 s->fmt_signed = 0;
234 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
235 if (-1 == s->time_const) {
236 if (s->freq <= 0)
237 s->freq = 11025;
239 else {
240 int tmp = (256 - s->time_const);
241 s->freq = (1000000 + (tmp / 2)) / tmp;
244 if (dma_len != -1) {
245 s->block_size = dma_len << s->fmt_stereo;
247 else {
248 /* This is apparently the only way to make both Act1/PL
249 and SecondReality/FC work
251 Act1 sets block size via command 0x48 and it's an odd number
252 SR does the same with even number
253 Both use stereo, and Creatives own documentation states that
254 0x48 sets block size in bytes less one.. go figure */
255 s->block_size &= ~s->fmt_stereo;
258 s->freq >>= s->fmt_stereo;
259 s->left_till_irq = s->block_size;
260 s->bytes_per_second = (s->freq << s->fmt_stereo);
261 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
262 s->dma_auto = (mask & DMA8_AUTO) != 0;
263 s->align = (1 << s->fmt_stereo) - 1;
265 if (s->block_size & s->align) {
266 qemu_log_mask(LOG_GUEST_ERROR, "warning: misaligned block size %d,"
267 " alignment %d\n", s->block_size, s->align + 1);
270 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
271 "dma %d, auto %d, fifo %d, high %d\n",
272 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
273 s->block_size, s->dma_auto, s->fifo, s->highspeed);
275 continue_dma8 (s);
276 speaker (s, 1);
279 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
281 s->use_hdma = cmd < 0xc0;
282 s->fifo = (cmd >> 1) & 1;
283 s->dma_auto = (cmd >> 2) & 1;
284 s->fmt_signed = (d0 >> 4) & 1;
285 s->fmt_stereo = (d0 >> 5) & 1;
287 switch (cmd >> 4) {
288 case 11:
289 s->fmt_bits = 16;
290 break;
292 case 12:
293 s->fmt_bits = 8;
294 break;
297 if (-1 != s->time_const) {
298 #if 1
299 int tmp = 256 - s->time_const;
300 s->freq = (1000000 + (tmp / 2)) / tmp;
301 #else
302 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
303 s->freq = 1000000 / ((255 - s->time_const));
304 #endif
305 s->time_const = -1;
308 s->block_size = dma_len + 1;
309 s->block_size <<= (s->fmt_bits == 16);
310 if (!s->dma_auto) {
311 /* It is clear that for DOOM and auto-init this value
312 shouldn't take stereo into account, while Miles Sound Systems
313 setsound.exe with single transfer mode wouldn't work without it
314 wonders of SB16 yet again */
315 s->block_size <<= s->fmt_stereo;
318 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
319 "dma %d, auto %d, fifo %d, high %d\n",
320 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
321 s->block_size, s->dma_auto, s->fifo, s->highspeed);
323 if (16 == s->fmt_bits) {
324 if (s->fmt_signed) {
325 s->fmt = AUDIO_FORMAT_S16;
327 else {
328 s->fmt = AUDIO_FORMAT_U16;
331 else {
332 if (s->fmt_signed) {
333 s->fmt = AUDIO_FORMAT_S8;
335 else {
336 s->fmt = AUDIO_FORMAT_U8;
340 s->left_till_irq = s->block_size;
342 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
343 s->highspeed = 0;
344 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
345 if (s->block_size & s->align) {
346 qemu_log_mask(LOG_GUEST_ERROR, "warning: misaligned block size %d,"
347 " alignment %d\n", s->block_size, s->align + 1);
350 if (s->freq) {
351 struct audsettings as;
353 s->audio_free = 0;
355 as.freq = s->freq;
356 as.nchannels = 1 << s->fmt_stereo;
357 as.fmt = s->fmt;
358 as.endianness = 0;
360 s->voice = AUD_open_out (
361 &s->card,
362 s->voice,
363 "sb16",
365 SB_audio_callback,
370 control (s, 1);
371 speaker (s, 1);
374 static inline void dsp_out_data (SB16State *s, uint8_t val)
376 ldebug ("outdata %#x\n", val);
377 if ((size_t) s->out_data_len < sizeof (s->out_data)) {
378 s->out_data[s->out_data_len++] = val;
382 static inline uint8_t dsp_get_data (SB16State *s)
384 if (s->in_index) {
385 return s->in2_data[--s->in_index];
387 else {
388 dolog ("buffer underflow\n");
389 return 0;
393 static void command (SB16State *s, uint8_t cmd)
395 ldebug ("command %#x\n", cmd);
397 if (cmd > 0xaf && cmd < 0xd0) {
398 if (cmd & 8) {
399 qemu_log_mask(LOG_UNIMP, "ADC not yet supported (command %#x)\n",
400 cmd);
403 switch (cmd >> 4) {
404 case 11:
405 case 12:
406 break;
407 default:
408 qemu_log_mask(LOG_GUEST_ERROR, "%#x wrong bits\n", cmd);
410 s->needed_bytes = 3;
412 else {
413 s->needed_bytes = 0;
415 switch (cmd) {
416 case 0x03:
417 dsp_out_data (s, 0x10); /* s->csp_param); */
418 goto warn;
420 case 0x04:
421 s->needed_bytes = 1;
422 goto warn;
424 case 0x05:
425 s->needed_bytes = 2;
426 goto warn;
428 case 0x08:
429 /* __asm__ ("int3"); */
430 goto warn;
432 case 0x0e:
433 s->needed_bytes = 2;
434 goto warn;
436 case 0x09:
437 dsp_out_data (s, 0xf8);
438 goto warn;
440 case 0x0f:
441 s->needed_bytes = 1;
442 goto warn;
444 case 0x10:
445 s->needed_bytes = 1;
446 goto warn;
448 case 0x14:
449 s->needed_bytes = 2;
450 s->block_size = 0;
451 break;
453 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
454 dma_cmd8 (s, DMA8_AUTO, -1);
455 break;
457 case 0x20: /* Direct ADC, Juice/PL */
458 dsp_out_data (s, 0xff);
459 goto warn;
461 case 0x35:
462 qemu_log_mask(LOG_UNIMP, "0x35 - MIDI command not implemented\n");
463 break;
465 case 0x40:
466 s->freq = -1;
467 s->time_const = -1;
468 s->needed_bytes = 1;
469 break;
471 case 0x41:
472 s->freq = -1;
473 s->time_const = -1;
474 s->needed_bytes = 2;
475 break;
477 case 0x42:
478 s->freq = -1;
479 s->time_const = -1;
480 s->needed_bytes = 2;
481 goto warn;
483 case 0x45:
484 dsp_out_data (s, 0xaa);
485 goto warn;
487 case 0x47: /* Continue Auto-Initialize DMA 16bit */
488 break;
490 case 0x48:
491 s->needed_bytes = 2;
492 break;
494 case 0x74:
495 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
496 qemu_log_mask(LOG_UNIMP, "0x75 - DMA DAC, 4-bit ADPCM not"
497 " implemented\n");
498 break;
500 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
501 s->needed_bytes = 2;
502 qemu_log_mask(LOG_UNIMP, "0x74 - DMA DAC, 4-bit ADPCM Reference not"
503 " implemented\n");
504 break;
506 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
507 s->needed_bytes = 2;
508 qemu_log_mask(LOG_UNIMP, "0x74 - DMA DAC, 2.6-bit ADPCM not"
509 " implemented\n");
510 break;
512 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
513 s->needed_bytes = 2;
514 qemu_log_mask(LOG_UNIMP, "0x74 - DMA DAC, 2.6-bit ADPCM Reference"
515 " not implemented\n");
516 break;
518 case 0x7d:
519 qemu_log_mask(LOG_UNIMP, "0x7d - Autio-Initialize DMA DAC, 4-bit"
520 " ADPCM Reference\n");
521 qemu_log_mask(LOG_UNIMP, "not implemented\n");
522 break;
524 case 0x7f:
525 qemu_log_mask(LOG_UNIMP, "0x7d - Autio-Initialize DMA DAC, 2.6-bit"
526 " ADPCM Reference\n");
527 qemu_log_mask(LOG_UNIMP, "not implemented\n");
528 break;
530 case 0x80:
531 s->needed_bytes = 2;
532 break;
534 case 0x90:
535 case 0x91:
536 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
537 break;
539 case 0xd0: /* halt DMA operation. 8bit */
540 control (s, 0);
541 break;
543 case 0xd1: /* speaker on */
544 speaker (s, 1);
545 break;
547 case 0xd3: /* speaker off */
548 speaker (s, 0);
549 break;
551 case 0xd4: /* continue DMA operation. 8bit */
552 /* KQ6 (or maybe Sierras audblst.drv in general) resets
553 the frequency between halt/continue */
554 continue_dma8 (s);
555 break;
557 case 0xd5: /* halt DMA operation. 16bit */
558 control (s, 0);
559 break;
561 case 0xd6: /* continue DMA operation. 16bit */
562 control (s, 1);
563 break;
565 case 0xd9: /* exit auto-init DMA after this block. 16bit */
566 s->dma_auto = 0;
567 break;
569 case 0xda: /* exit auto-init DMA after this block. 8bit */
570 s->dma_auto = 0;
571 break;
573 case 0xe0: /* DSP identification */
574 s->needed_bytes = 1;
575 break;
577 case 0xe1:
578 dsp_out_data (s, s->ver & 0xff);
579 dsp_out_data (s, s->ver >> 8);
580 break;
582 case 0xe2:
583 s->needed_bytes = 1;
584 goto warn;
586 case 0xe3:
588 int i;
589 for (i = sizeof (e3) - 1; i >= 0; --i)
590 dsp_out_data (s, e3[i]);
592 break;
594 case 0xe4: /* write test reg */
595 s->needed_bytes = 1;
596 break;
598 case 0xe7:
599 qemu_log_mask(LOG_UNIMP, "Attempt to probe for ESS (0xe7)?\n");
600 break;
602 case 0xe8: /* read test reg */
603 dsp_out_data (s, s->test_reg);
604 break;
606 case 0xf2:
607 case 0xf3:
608 dsp_out_data (s, 0xaa);
609 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
610 qemu_irq_raise (s->pic);
611 break;
613 case 0xf9:
614 s->needed_bytes = 1;
615 goto warn;
617 case 0xfa:
618 dsp_out_data (s, 0);
619 goto warn;
621 case 0xfc: /* FIXME */
622 dsp_out_data (s, 0);
623 goto warn;
625 default:
626 qemu_log_mask(LOG_UNIMP, "Unrecognized command %#x\n", cmd);
627 break;
631 if (!s->needed_bytes) {
632 ldebug ("\n");
635 exit:
636 if (!s->needed_bytes) {
637 s->cmd = -1;
639 else {
640 s->cmd = cmd;
642 return;
644 warn:
645 qemu_log_mask(LOG_UNIMP, "warning: command %#x,%d is not truly understood"
646 " yet\n", cmd, s->needed_bytes);
647 goto exit;
651 static uint16_t dsp_get_lohi (SB16State *s)
653 uint8_t hi = dsp_get_data (s);
654 uint8_t lo = dsp_get_data (s);
655 return (hi << 8) | lo;
658 static uint16_t dsp_get_hilo (SB16State *s)
660 uint8_t lo = dsp_get_data (s);
661 uint8_t hi = dsp_get_data (s);
662 return (hi << 8) | lo;
665 static void complete (SB16State *s)
667 int d0, d1, d2;
668 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
669 s->cmd, s->in_index, s->needed_bytes);
671 if (s->cmd > 0xaf && s->cmd < 0xd0) {
672 d2 = dsp_get_data (s);
673 d1 = dsp_get_data (s);
674 d0 = dsp_get_data (s);
676 if (s->cmd & 8) {
677 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
678 s->cmd, d0, d1, d2);
680 else {
681 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
682 s->cmd, d0, d1, d2);
683 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
686 else {
687 switch (s->cmd) {
688 case 0x04:
689 s->csp_mode = dsp_get_data (s);
690 s->csp_reg83r = 0;
691 s->csp_reg83w = 0;
692 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
693 break;
695 case 0x05:
696 s->csp_param = dsp_get_data (s);
697 s->csp_value = dsp_get_data (s);
698 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
699 s->csp_param,
700 s->csp_value);
701 break;
703 case 0x0e:
704 d0 = dsp_get_data (s);
705 d1 = dsp_get_data (s);
706 ldebug ("write CSP register %d <- %#x\n", d1, d0);
707 if (d1 == 0x83) {
708 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
709 s->csp_reg83[s->csp_reg83r % 4] = d0;
710 s->csp_reg83r += 1;
712 else {
713 s->csp_regs[d1] = d0;
715 break;
717 case 0x0f:
718 d0 = dsp_get_data (s);
719 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
720 d0, s->csp_regs[d0], s->csp_mode);
721 if (d0 == 0x83) {
722 ldebug ("0x83[%d] -> %#x\n",
723 s->csp_reg83w,
724 s->csp_reg83[s->csp_reg83w % 4]);
725 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
726 s->csp_reg83w += 1;
728 else {
729 dsp_out_data (s, s->csp_regs[d0]);
731 break;
733 case 0x10:
734 d0 = dsp_get_data (s);
735 dolog ("cmd 0x10 d0=%#x\n", d0);
736 break;
738 case 0x14:
739 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
740 break;
742 case 0x40:
743 s->time_const = dsp_get_data (s);
744 ldebug ("set time const %d\n", s->time_const);
745 break;
747 case 0x41:
748 case 0x42:
750 * 0x41 is documented as setting the output sample rate,
751 * and 0x42 the input sample rate, but in fact SB16 hardware
752 * seems to have only a single sample rate under the hood,
753 * and FT2 sets output freq with this (go figure). Compare:
754 * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
756 s->freq = dsp_get_hilo (s);
757 ldebug ("set freq %d\n", s->freq);
758 break;
760 case 0x48:
761 s->block_size = dsp_get_lohi (s) + 1;
762 ldebug ("set dma block len %d\n", s->block_size);
763 break;
765 case 0x74:
766 case 0x75:
767 case 0x76:
768 case 0x77:
769 /* ADPCM stuff, ignore */
770 break;
772 case 0x80:
774 int freq, samples, bytes;
775 int64_t ticks;
777 freq = s->freq > 0 ? s->freq : 11025;
778 samples = dsp_get_lohi (s) + 1;
779 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
780 ticks = muldiv64(bytes, NANOSECONDS_PER_SECOND, freq);
781 if (ticks < NANOSECONDS_PER_SECOND / 1024) {
782 qemu_irq_raise (s->pic);
784 else {
785 if (s->aux_ts) {
786 timer_mod (
787 s->aux_ts,
788 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks
792 ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
794 break;
796 case 0xe0:
797 d0 = dsp_get_data (s);
798 s->out_data_len = 0;
799 ldebug ("E0 data = %#x\n", d0);
800 dsp_out_data (s, ~d0);
801 break;
803 case 0xe2:
804 #ifdef DEBUG
805 d0 = dsp_get_data (s);
806 dolog ("E2 = %#x\n", d0);
807 #endif
808 break;
810 case 0xe4:
811 s->test_reg = dsp_get_data (s);
812 break;
814 case 0xf9:
815 d0 = dsp_get_data (s);
816 ldebug ("command 0xf9 with %#x\n", d0);
817 switch (d0) {
818 case 0x0e:
819 dsp_out_data (s, 0xff);
820 break;
822 case 0x0f:
823 dsp_out_data (s, 0x07);
824 break;
826 case 0x37:
827 dsp_out_data (s, 0x38);
828 break;
830 default:
831 dsp_out_data (s, 0x00);
832 break;
834 break;
836 default:
837 qemu_log_mask(LOG_UNIMP, "complete: unrecognized command %#x\n",
838 s->cmd);
839 return;
843 ldebug ("\n");
844 s->cmd = -1;
847 static void legacy_reset (SB16State *s)
849 struct audsettings as;
851 s->freq = 11025;
852 s->fmt_signed = 0;
853 s->fmt_bits = 8;
854 s->fmt_stereo = 0;
856 as.freq = s->freq;
857 as.nchannels = 1;
858 as.fmt = AUDIO_FORMAT_U8;
859 as.endianness = 0;
861 s->voice = AUD_open_out (
862 &s->card,
863 s->voice,
864 "sb16",
866 SB_audio_callback,
870 /* Not sure about that... */
871 /* AUD_set_active_out (s->voice, 1); */
874 static void reset (SB16State *s)
876 qemu_irq_lower (s->pic);
877 if (s->dma_auto) {
878 qemu_irq_raise (s->pic);
879 qemu_irq_lower (s->pic);
882 s->mixer_regs[0x82] = 0;
883 s->dma_auto = 0;
884 s->in_index = 0;
885 s->out_data_len = 0;
886 s->left_till_irq = 0;
887 s->needed_bytes = 0;
888 s->block_size = -1;
889 s->nzero = 0;
890 s->highspeed = 0;
891 s->v2x6 = 0;
892 s->cmd = -1;
894 dsp_out_data (s, 0xaa);
895 speaker (s, 0);
896 control (s, 0);
897 legacy_reset (s);
900 static void dsp_write(void *opaque, uint32_t nport, uint32_t val)
902 SB16State *s = opaque;
903 int iport;
905 iport = nport - s->port;
907 ldebug ("write %#x <- %#x\n", nport, val);
908 switch (iport) {
909 case 0x06:
910 switch (val) {
911 case 0x00:
912 if (s->v2x6 == 1) {
913 reset (s);
915 s->v2x6 = 0;
916 break;
918 case 0x01:
919 case 0x03: /* FreeBSD kludge */
920 s->v2x6 = 1;
921 break;
923 case 0xc6:
924 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
925 break;
927 case 0xb8: /* Panic */
928 reset (s);
929 break;
931 case 0x39:
932 dsp_out_data (s, 0x38);
933 reset (s);
934 s->v2x6 = 0x39;
935 break;
937 default:
938 s->v2x6 = val;
939 break;
941 break;
943 case 0x0c: /* write data or command | write status */
944 /* if (s->highspeed) */
945 /* break; */
947 if (s->needed_bytes == 0) {
948 command (s, val);
949 #if 0
950 if (0 == s->needed_bytes) {
951 log_dsp (s);
953 #endif
955 else {
956 if (s->in_index == sizeof (s->in2_data)) {
957 dolog ("in data overrun\n");
959 else {
960 s->in2_data[s->in_index++] = val;
961 if (s->in_index == s->needed_bytes) {
962 s->needed_bytes = 0;
963 complete (s);
964 #if 0
965 log_dsp (s);
966 #endif
970 break;
972 default:
973 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
974 break;
978 static uint32_t dsp_read(void *opaque, uint32_t nport)
980 SB16State *s = opaque;
981 int iport, retval, ack = 0;
983 iport = nport - s->port;
985 switch (iport) {
986 case 0x06: /* reset */
987 retval = 0xff;
988 break;
990 case 0x0a: /* read data */
991 if (s->out_data_len) {
992 retval = s->out_data[--s->out_data_len];
993 s->last_read_byte = retval;
995 else {
996 if (s->cmd != -1) {
997 dolog ("empty output buffer for command %#x\n",
998 s->cmd);
1000 retval = s->last_read_byte;
1001 /* goto error; */
1003 break;
1005 case 0x0c: /* 0 can write */
1006 retval = s->can_write ? 0 : 0x80;
1007 break;
1009 case 0x0d: /* timer interrupt clear */
1010 /* dolog ("timer interrupt clear\n"); */
1011 retval = 0;
1012 break;
1014 case 0x0e: /* data available status | irq 8 ack */
1015 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1016 if (s->mixer_regs[0x82] & 1) {
1017 ack = 1;
1018 s->mixer_regs[0x82] &= ~1;
1019 qemu_irq_lower (s->pic);
1021 break;
1023 case 0x0f: /* irq 16 ack */
1024 retval = 0xff;
1025 if (s->mixer_regs[0x82] & 2) {
1026 ack = 1;
1027 s->mixer_regs[0x82] &= ~2;
1028 qemu_irq_lower (s->pic);
1030 break;
1032 default:
1033 goto error;
1036 if (!ack) {
1037 ldebug ("read %#x -> %#x\n", nport, retval);
1040 return retval;
1042 error:
1043 dolog ("warning: dsp_read %#x error\n", nport);
1044 return 0xff;
1047 static void reset_mixer (SB16State *s)
1049 int i;
1051 memset (s->mixer_regs, 0xff, 0x7f);
1052 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1054 s->mixer_regs[0x02] = 4; /* master volume 3bits */
1055 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
1056 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
1057 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1059 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1060 s->mixer_regs[0x0c] = 0;
1062 /* d5=output filt, d1=stereo switch */
1063 s->mixer_regs[0x0e] = 0;
1065 /* voice volume L d5,d7, R d1,d3 */
1066 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1067 /* master ... */
1068 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1069 /* MIDI ... */
1070 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1072 for (i = 0x30; i < 0x48; i++) {
1073 s->mixer_regs[i] = 0x20;
1077 static void mixer_write_indexb(void *opaque, uint32_t nport, uint32_t val)
1079 SB16State *s = opaque;
1080 (void) nport;
1081 s->mixer_nreg = val;
1084 static void mixer_write_datab(void *opaque, uint32_t nport, uint32_t val)
1086 SB16State *s = opaque;
1088 (void) nport;
1089 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1091 switch (s->mixer_nreg) {
1092 case 0x00:
1093 reset_mixer (s);
1094 break;
1096 case 0x80:
1098 int irq = irq_of_magic (val);
1099 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1100 if (irq > 0) {
1101 s->irq = irq;
1104 break;
1106 case 0x81:
1108 int dma, hdma;
1110 dma = ctz32 (val & 0xf);
1111 hdma = ctz32 (val & 0xf0);
1112 if (dma != s->dma || hdma != s->hdma) {
1113 qemu_log_mask(LOG_GUEST_ERROR, "attempt to change DMA 8bit"
1114 " %d(%d), 16bit %d(%d) (val=%#x)\n", dma, s->dma,
1115 hdma, s->hdma, val);
1117 #if 0
1118 s->dma = dma;
1119 s->hdma = hdma;
1120 #endif
1122 break;
1124 case 0x82:
1125 qemu_log_mask(LOG_GUEST_ERROR, "attempt to write into IRQ status"
1126 " register (val=%#x)\n", val);
1127 return;
1129 default:
1130 if (s->mixer_nreg >= 0x80) {
1131 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1133 break;
1136 s->mixer_regs[s->mixer_nreg] = val;
1139 static uint32_t mixer_read(void *opaque, uint32_t nport)
1141 SB16State *s = opaque;
1143 (void) nport;
1144 #ifndef DEBUG_SB16_MOST
1145 if (s->mixer_nreg != 0x82) {
1146 ldebug ("mixer_read[%#x] -> %#x\n",
1147 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1149 #else
1150 ldebug ("mixer_read[%#x] -> %#x\n",
1151 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1152 #endif
1153 return s->mixer_regs[s->mixer_nreg];
1156 static int write_audio (SB16State *s, int nchan, int dma_pos,
1157 int dma_len, int len)
1159 IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma;
1160 IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
1161 int temp, net;
1162 uint8_t tmpbuf[4096];
1164 temp = len;
1165 net = 0;
1167 while (temp) {
1168 int left = dma_len - dma_pos;
1169 int copied;
1170 size_t to_copy;
1172 to_copy = MIN (temp, left);
1173 if (to_copy > sizeof (tmpbuf)) {
1174 to_copy = sizeof (tmpbuf);
1177 copied = k->read_memory(isa_dma, nchan, tmpbuf, dma_pos, to_copy);
1178 copied = AUD_write (s->voice, tmpbuf, copied);
1180 temp -= copied;
1181 dma_pos = (dma_pos + copied) % dma_len;
1182 net += copied;
1184 if (!copied) {
1185 break;
1189 return net;
1192 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1194 SB16State *s = opaque;
1195 int till, copy, written, free;
1197 if (s->block_size <= 0) {
1198 qemu_log_mask(LOG_GUEST_ERROR, "invalid block size=%d nchan=%d"
1199 " dma_pos=%d dma_len=%d\n", s->block_size, nchan,
1200 dma_pos, dma_len);
1201 return dma_pos;
1204 if (s->left_till_irq < 0) {
1205 s->left_till_irq = s->block_size;
1208 if (s->voice) {
1209 free = s->audio_free & ~s->align;
1210 if ((free <= 0) || !dma_len) {
1211 return dma_pos;
1214 else {
1215 free = dma_len;
1218 copy = free;
1219 till = s->left_till_irq;
1221 #ifdef DEBUG_SB16_MOST
1222 dolog ("pos:%06d %d till:%d len:%d\n",
1223 dma_pos, free, till, dma_len);
1224 #endif
1226 if (till <= copy) {
1227 if (s->dma_auto == 0) {
1228 copy = till;
1232 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1233 dma_pos = (dma_pos + written) % dma_len;
1234 s->left_till_irq -= written;
1236 if (s->left_till_irq <= 0) {
1237 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1238 qemu_irq_raise (s->pic);
1239 if (s->dma_auto == 0) {
1240 control (s, 0);
1241 speaker (s, 0);
1245 #ifdef DEBUG_SB16_MOST
1246 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1247 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1248 s->block_size);
1249 #endif
1251 while (s->left_till_irq <= 0) {
1252 s->left_till_irq = s->block_size + s->left_till_irq;
1255 return dma_pos;
1258 static void SB_audio_callback (void *opaque, int free)
1260 SB16State *s = opaque;
1261 s->audio_free = free;
1264 static int sb16_post_load (void *opaque, int version_id)
1266 SB16State *s = opaque;
1268 if (s->voice) {
1269 AUD_close_out (&s->card, s->voice);
1270 s->voice = NULL;
1273 if (s->dma_running) {
1274 if (s->freq) {
1275 struct audsettings as;
1277 s->audio_free = 0;
1279 as.freq = s->freq;
1280 as.nchannels = 1 << s->fmt_stereo;
1281 as.fmt = s->fmt;
1282 as.endianness = 0;
1284 s->voice = AUD_open_out (
1285 &s->card,
1286 s->voice,
1287 "sb16",
1289 SB_audio_callback,
1294 control (s, 1);
1295 speaker (s, s->speaker);
1297 return 0;
1300 static const VMStateDescription vmstate_sb16 = {
1301 .name = "sb16",
1302 .version_id = 1,
1303 .minimum_version_id = 1,
1304 .post_load = sb16_post_load,
1305 .fields = (VMStateField[]) {
1306 VMSTATE_UINT32 (irq, SB16State),
1307 VMSTATE_UINT32 (dma, SB16State),
1308 VMSTATE_UINT32 (hdma, SB16State),
1309 VMSTATE_UINT32 (port, SB16State),
1310 VMSTATE_UINT32 (ver, SB16State),
1311 VMSTATE_INT32 (in_index, SB16State),
1312 VMSTATE_INT32 (out_data_len, SB16State),
1313 VMSTATE_INT32 (fmt_stereo, SB16State),
1314 VMSTATE_INT32 (fmt_signed, SB16State),
1315 VMSTATE_INT32 (fmt_bits, SB16State),
1316 VMSTATE_UINT32 (fmt, SB16State),
1317 VMSTATE_INT32 (dma_auto, SB16State),
1318 VMSTATE_INT32 (block_size, SB16State),
1319 VMSTATE_INT32 (fifo, SB16State),
1320 VMSTATE_INT32 (freq, SB16State),
1321 VMSTATE_INT32 (time_const, SB16State),
1322 VMSTATE_INT32 (speaker, SB16State),
1323 VMSTATE_INT32 (needed_bytes, SB16State),
1324 VMSTATE_INT32 (cmd, SB16State),
1325 VMSTATE_INT32 (use_hdma, SB16State),
1326 VMSTATE_INT32 (highspeed, SB16State),
1327 VMSTATE_INT32 (can_write, SB16State),
1328 VMSTATE_INT32 (v2x6, SB16State),
1330 VMSTATE_UINT8 (csp_param, SB16State),
1331 VMSTATE_UINT8 (csp_value, SB16State),
1332 VMSTATE_UINT8 (csp_mode, SB16State),
1333 VMSTATE_UINT8 (csp_param, SB16State),
1334 VMSTATE_BUFFER (csp_regs, SB16State),
1335 VMSTATE_UINT8 (csp_index, SB16State),
1336 VMSTATE_BUFFER (csp_reg83, SB16State),
1337 VMSTATE_INT32 (csp_reg83r, SB16State),
1338 VMSTATE_INT32 (csp_reg83w, SB16State),
1340 VMSTATE_BUFFER (in2_data, SB16State),
1341 VMSTATE_BUFFER (out_data, SB16State),
1342 VMSTATE_UINT8 (test_reg, SB16State),
1343 VMSTATE_UINT8 (last_read_byte, SB16State),
1345 VMSTATE_INT32 (nzero, SB16State),
1346 VMSTATE_INT32 (left_till_irq, SB16State),
1347 VMSTATE_INT32 (dma_running, SB16State),
1348 VMSTATE_INT32 (bytes_per_second, SB16State),
1349 VMSTATE_INT32 (align, SB16State),
1351 VMSTATE_INT32 (mixer_nreg, SB16State),
1352 VMSTATE_BUFFER (mixer_regs, SB16State),
1354 VMSTATE_END_OF_LIST ()
1358 static const MemoryRegionPortio sb16_ioport_list[] = {
1359 { 4, 1, 1, .write = mixer_write_indexb },
1360 { 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
1361 { 6, 1, 1, .read = dsp_read, .write = dsp_write },
1362 { 10, 1, 1, .read = dsp_read },
1363 { 12, 1, 1, .write = dsp_write },
1364 { 12, 4, 1, .read = dsp_read },
1365 PORTIO_END_OF_LIST (),
1369 static void sb16_initfn (Object *obj)
1371 SB16State *s = SB16 (obj);
1373 s->cmd = -1;
1376 static void sb16_realizefn (DeviceState *dev, Error **errp)
1378 ISADevice *isadev = ISA_DEVICE (dev);
1379 SB16State *s = SB16 (dev);
1380 IsaDmaClass *k;
1382 s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
1383 s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
1384 if (!s->isa_dma || !s->isa_hdma) {
1385 error_setg(errp, "ISA controller does not support DMA");
1386 return;
1389 isa_init_irq (isadev, &s->pic, s->irq);
1391 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1392 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1393 s->mixer_regs[0x82] = 2 << 5;
1395 s->csp_regs[5] = 1;
1396 s->csp_regs[9] = 0xf8;
1398 reset_mixer (s);
1399 s->aux_ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, aux_timer, s);
1400 if (!s->aux_ts) {
1401 error_setg(errp, "warning: Could not create auxiliary timer");
1404 isa_register_portio_list(isadev, &s->portio_list, s->port,
1405 sb16_ioport_list, s, "sb16");
1407 k = ISADMA_GET_CLASS(s->isa_hdma);
1408 k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s);
1410 k = ISADMA_GET_CLASS(s->isa_dma);
1411 k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);
1413 s->can_write = 1;
1415 AUD_register_card ("sb16", &s->card);
1418 static Property sb16_properties[] = {
1419 DEFINE_AUDIO_PROPERTIES(SB16State, card),
1420 DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */
1421 DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220),
1422 DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5),
1423 DEFINE_PROP_UINT32 ("dma", SB16State, dma, 1),
1424 DEFINE_PROP_UINT32 ("dma16", SB16State, hdma, 5),
1425 DEFINE_PROP_END_OF_LIST (),
1428 static void sb16_class_initfn (ObjectClass *klass, void *data)
1430 DeviceClass *dc = DEVICE_CLASS (klass);
1432 dc->realize = sb16_realizefn;
1433 set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
1434 dc->desc = "Creative Sound Blaster 16";
1435 dc->vmsd = &vmstate_sb16;
1436 device_class_set_props(dc, sb16_properties);
1439 static const TypeInfo sb16_info = {
1440 .name = TYPE_SB16,
1441 .parent = TYPE_ISA_DEVICE,
1442 .instance_size = sizeof (SB16State),
1443 .instance_init = sb16_initfn,
1444 .class_init = sb16_class_initfn,
1447 static void sb16_register_types (void)
1449 type_register_static (&sb16_info);
1450 deprecated_register_soundhw("sb16", "Creative Sound Blaster 16",
1451 1, TYPE_SB16);
1454 type_init (sb16_register_types)