hw/misc/a9scu: Report unimplemented accesses with qemu_log_mask(UNIMP)
[qemu/ar7.git] / hw / audio / sb16.c
blob6aa2c0fb93aa6d64e2899572ed112c53b6c42a6b
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"
37 #include "qom/object.h"
39 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
41 /* #define DEBUG */
42 /* #define DEBUG_SB16_MOST */
44 #ifdef DEBUG
45 #define ldebug(...) dolog (__VA_ARGS__)
46 #else
47 #define ldebug(...)
48 #endif
50 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
52 #define TYPE_SB16 "sb16"
53 typedef struct SB16State SB16State;
54 DECLARE_INSTANCE_CHECKER(SB16State, SB16,
55 TYPE_SB16)
57 struct SB16State {
58 ISADevice parent_obj;
60 QEMUSoundCard card;
61 qemu_irq pic;
62 uint32_t irq;
63 uint32_t dma;
64 uint32_t hdma;
65 uint32_t port;
66 uint32_t ver;
67 IsaDma *isa_dma;
68 IsaDma *isa_hdma;
70 int in_index;
71 int out_data_len;
72 int fmt_stereo;
73 int fmt_signed;
74 int fmt_bits;
75 AudioFormat fmt;
76 int dma_auto;
77 int block_size;
78 int fifo;
79 int freq;
80 int time_const;
81 int speaker;
82 int needed_bytes;
83 int cmd;
84 int use_hdma;
85 int highspeed;
86 int can_write;
88 int v2x6;
90 uint8_t csp_param;
91 uint8_t csp_value;
92 uint8_t csp_mode;
93 uint8_t csp_regs[256];
94 uint8_t csp_index;
95 uint8_t csp_reg83[4];
96 int csp_reg83r;
97 int csp_reg83w;
99 uint8_t in2_data[10];
100 uint8_t out_data[50];
101 uint8_t test_reg;
102 uint8_t last_read_byte;
103 int nzero;
105 int left_till_irq;
107 int dma_running;
108 int bytes_per_second;
109 int align;
110 int audio_free;
111 SWVoiceOut *voice;
113 QEMUTimer *aux_ts;
114 /* mixer state */
115 int mixer_nreg;
116 uint8_t mixer_regs[256];
117 PortioList portio_list;
120 static void SB_audio_callback (void *opaque, int free);
122 static int magic_of_irq (int irq)
124 switch (irq) {
125 case 5:
126 return 2;
127 case 7:
128 return 4;
129 case 9:
130 return 1;
131 case 10:
132 return 8;
133 default:
134 qemu_log_mask(LOG_GUEST_ERROR, "bad irq %d\n", irq);
135 return 2;
139 static int irq_of_magic (int magic)
141 switch (magic) {
142 case 1:
143 return 9;
144 case 2:
145 return 5;
146 case 4:
147 return 7;
148 case 8:
149 return 10;
150 default:
151 qemu_log_mask(LOG_GUEST_ERROR, "bad irq magic %d\n", magic);
152 return -1;
156 #if 0
157 static void log_dsp (SB16State *dsp)
159 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
160 dsp->fmt_stereo ? "Stereo" : "Mono",
161 dsp->fmt_signed ? "Signed" : "Unsigned",
162 dsp->fmt_bits,
163 dsp->dma_auto ? "Auto" : "Single",
164 dsp->block_size,
165 dsp->freq,
166 dsp->time_const,
167 dsp->speaker);
169 #endif
171 static void speaker (SB16State *s, int on)
173 s->speaker = on;
174 /* AUD_enable (s->voice, on); */
177 static void control (SB16State *s, int hold)
179 int dma = s->use_hdma ? s->hdma : s->dma;
180 IsaDma *isa_dma = s->use_hdma ? s->isa_hdma : s->isa_dma;
181 IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
182 s->dma_running = hold;
184 ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
186 if (hold) {
187 k->hold_DREQ(isa_dma, dma);
188 AUD_set_active_out (s->voice, 1);
190 else {
191 k->release_DREQ(isa_dma, dma);
192 AUD_set_active_out (s->voice, 0);
196 static void aux_timer (void *opaque)
198 SB16State *s = opaque;
199 s->can_write = 1;
200 qemu_irq_raise (s->pic);
203 #define DMA8_AUTO 1
204 #define DMA8_HIGH 2
206 static void continue_dma8 (SB16State *s)
208 if (s->freq > 0) {
209 struct audsettings as;
211 s->audio_free = 0;
213 as.freq = s->freq;
214 as.nchannels = 1 << s->fmt_stereo;
215 as.fmt = s->fmt;
216 as.endianness = 0;
218 s->voice = AUD_open_out (
219 &s->card,
220 s->voice,
221 "sb16",
223 SB_audio_callback,
228 control (s, 1);
231 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
233 s->fmt = AUDIO_FORMAT_U8;
234 s->use_hdma = 0;
235 s->fmt_bits = 8;
236 s->fmt_signed = 0;
237 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
238 if (-1 == s->time_const) {
239 if (s->freq <= 0)
240 s->freq = 11025;
242 else {
243 int tmp = (256 - s->time_const);
244 s->freq = (1000000 + (tmp / 2)) / tmp;
247 if (dma_len != -1) {
248 s->block_size = dma_len << s->fmt_stereo;
250 else {
251 /* This is apparently the only way to make both Act1/PL
252 and SecondReality/FC work
254 Act1 sets block size via command 0x48 and it's an odd number
255 SR does the same with even number
256 Both use stereo, and Creatives own documentation states that
257 0x48 sets block size in bytes less one.. go figure */
258 s->block_size &= ~s->fmt_stereo;
261 s->freq >>= s->fmt_stereo;
262 s->left_till_irq = s->block_size;
263 s->bytes_per_second = (s->freq << s->fmt_stereo);
264 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
265 s->dma_auto = (mask & DMA8_AUTO) != 0;
266 s->align = (1 << s->fmt_stereo) - 1;
268 if (s->block_size & s->align) {
269 qemu_log_mask(LOG_GUEST_ERROR, "warning: misaligned block size %d,"
270 " alignment %d\n", s->block_size, s->align + 1);
273 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
274 "dma %d, auto %d, fifo %d, high %d\n",
275 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
276 s->block_size, s->dma_auto, s->fifo, s->highspeed);
278 continue_dma8 (s);
279 speaker (s, 1);
282 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
284 s->use_hdma = cmd < 0xc0;
285 s->fifo = (cmd >> 1) & 1;
286 s->dma_auto = (cmd >> 2) & 1;
287 s->fmt_signed = (d0 >> 4) & 1;
288 s->fmt_stereo = (d0 >> 5) & 1;
290 switch (cmd >> 4) {
291 case 11:
292 s->fmt_bits = 16;
293 break;
295 case 12:
296 s->fmt_bits = 8;
297 break;
300 if (-1 != s->time_const) {
301 #if 1
302 int tmp = 256 - s->time_const;
303 s->freq = (1000000 + (tmp / 2)) / tmp;
304 #else
305 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
306 s->freq = 1000000 / ((255 - s->time_const));
307 #endif
308 s->time_const = -1;
311 s->block_size = dma_len + 1;
312 s->block_size <<= (s->fmt_bits == 16);
313 if (!s->dma_auto) {
314 /* It is clear that for DOOM and auto-init this value
315 shouldn't take stereo into account, while Miles Sound Systems
316 setsound.exe with single transfer mode wouldn't work without it
317 wonders of SB16 yet again */
318 s->block_size <<= s->fmt_stereo;
321 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
322 "dma %d, auto %d, fifo %d, high %d\n",
323 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
324 s->block_size, s->dma_auto, s->fifo, s->highspeed);
326 if (16 == s->fmt_bits) {
327 if (s->fmt_signed) {
328 s->fmt = AUDIO_FORMAT_S16;
330 else {
331 s->fmt = AUDIO_FORMAT_U16;
334 else {
335 if (s->fmt_signed) {
336 s->fmt = AUDIO_FORMAT_S8;
338 else {
339 s->fmt = AUDIO_FORMAT_U8;
343 s->left_till_irq = s->block_size;
345 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
346 s->highspeed = 0;
347 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
348 if (s->block_size & s->align) {
349 qemu_log_mask(LOG_GUEST_ERROR, "warning: misaligned block size %d,"
350 " alignment %d\n", s->block_size, s->align + 1);
353 if (s->freq) {
354 struct audsettings as;
356 s->audio_free = 0;
358 as.freq = s->freq;
359 as.nchannels = 1 << s->fmt_stereo;
360 as.fmt = s->fmt;
361 as.endianness = 0;
363 s->voice = AUD_open_out (
364 &s->card,
365 s->voice,
366 "sb16",
368 SB_audio_callback,
373 control (s, 1);
374 speaker (s, 1);
377 static inline void dsp_out_data (SB16State *s, uint8_t val)
379 ldebug ("outdata %#x\n", val);
380 if ((size_t) s->out_data_len < sizeof (s->out_data)) {
381 s->out_data[s->out_data_len++] = val;
385 static inline uint8_t dsp_get_data (SB16State *s)
387 if (s->in_index) {
388 return s->in2_data[--s->in_index];
390 else {
391 dolog ("buffer underflow\n");
392 return 0;
396 static void command (SB16State *s, uint8_t cmd)
398 ldebug ("command %#x\n", cmd);
400 if (cmd > 0xaf && cmd < 0xd0) {
401 if (cmd & 8) {
402 qemu_log_mask(LOG_UNIMP, "ADC not yet supported (command %#x)\n",
403 cmd);
406 switch (cmd >> 4) {
407 case 11:
408 case 12:
409 break;
410 default:
411 qemu_log_mask(LOG_GUEST_ERROR, "%#x wrong bits\n", cmd);
413 s->needed_bytes = 3;
415 else {
416 s->needed_bytes = 0;
418 switch (cmd) {
419 case 0x03:
420 dsp_out_data (s, 0x10); /* s->csp_param); */
421 goto warn;
423 case 0x04:
424 s->needed_bytes = 1;
425 goto warn;
427 case 0x05:
428 s->needed_bytes = 2;
429 goto warn;
431 case 0x08:
432 /* __asm__ ("int3"); */
433 goto warn;
435 case 0x0e:
436 s->needed_bytes = 2;
437 goto warn;
439 case 0x09:
440 dsp_out_data (s, 0xf8);
441 goto warn;
443 case 0x0f:
444 s->needed_bytes = 1;
445 goto warn;
447 case 0x10:
448 s->needed_bytes = 1;
449 goto warn;
451 case 0x14:
452 s->needed_bytes = 2;
453 s->block_size = 0;
454 break;
456 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
457 dma_cmd8 (s, DMA8_AUTO, -1);
458 break;
460 case 0x20: /* Direct ADC, Juice/PL */
461 dsp_out_data (s, 0xff);
462 goto warn;
464 case 0x35:
465 qemu_log_mask(LOG_UNIMP, "0x35 - MIDI command not implemented\n");
466 break;
468 case 0x40:
469 s->freq = -1;
470 s->time_const = -1;
471 s->needed_bytes = 1;
472 break;
474 case 0x41:
475 s->freq = -1;
476 s->time_const = -1;
477 s->needed_bytes = 2;
478 break;
480 case 0x42:
481 s->freq = -1;
482 s->time_const = -1;
483 s->needed_bytes = 2;
484 goto warn;
486 case 0x45:
487 dsp_out_data (s, 0xaa);
488 goto warn;
490 case 0x47: /* Continue Auto-Initialize DMA 16bit */
491 break;
493 case 0x48:
494 s->needed_bytes = 2;
495 break;
497 case 0x74:
498 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
499 qemu_log_mask(LOG_UNIMP, "0x75 - DMA DAC, 4-bit ADPCM not"
500 " implemented\n");
501 break;
503 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
504 s->needed_bytes = 2;
505 qemu_log_mask(LOG_UNIMP, "0x74 - DMA DAC, 4-bit ADPCM Reference not"
506 " implemented\n");
507 break;
509 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
510 s->needed_bytes = 2;
511 qemu_log_mask(LOG_UNIMP, "0x74 - DMA DAC, 2.6-bit ADPCM not"
512 " implemented\n");
513 break;
515 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
516 s->needed_bytes = 2;
517 qemu_log_mask(LOG_UNIMP, "0x74 - DMA DAC, 2.6-bit ADPCM Reference"
518 " not implemented\n");
519 break;
521 case 0x7d:
522 qemu_log_mask(LOG_UNIMP, "0x7d - Autio-Initialize DMA DAC, 4-bit"
523 " ADPCM Reference\n");
524 qemu_log_mask(LOG_UNIMP, "not implemented\n");
525 break;
527 case 0x7f:
528 qemu_log_mask(LOG_UNIMP, "0x7d - Autio-Initialize DMA DAC, 2.6-bit"
529 " ADPCM Reference\n");
530 qemu_log_mask(LOG_UNIMP, "not implemented\n");
531 break;
533 case 0x80:
534 s->needed_bytes = 2;
535 break;
537 case 0x90:
538 case 0x91:
539 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
540 break;
542 case 0xd0: /* halt DMA operation. 8bit */
543 control (s, 0);
544 break;
546 case 0xd1: /* speaker on */
547 speaker (s, 1);
548 break;
550 case 0xd3: /* speaker off */
551 speaker (s, 0);
552 break;
554 case 0xd4: /* continue DMA operation. 8bit */
555 /* KQ6 (or maybe Sierras audblst.drv in general) resets
556 the frequency between halt/continue */
557 continue_dma8 (s);
558 break;
560 case 0xd5: /* halt DMA operation. 16bit */
561 control (s, 0);
562 break;
564 case 0xd6: /* continue DMA operation. 16bit */
565 control (s, 1);
566 break;
568 case 0xd9: /* exit auto-init DMA after this block. 16bit */
569 s->dma_auto = 0;
570 break;
572 case 0xda: /* exit auto-init DMA after this block. 8bit */
573 s->dma_auto = 0;
574 break;
576 case 0xe0: /* DSP identification */
577 s->needed_bytes = 1;
578 break;
580 case 0xe1:
581 dsp_out_data (s, s->ver & 0xff);
582 dsp_out_data (s, s->ver >> 8);
583 break;
585 case 0xe2:
586 s->needed_bytes = 1;
587 goto warn;
589 case 0xe3:
591 int i;
592 for (i = sizeof (e3) - 1; i >= 0; --i)
593 dsp_out_data (s, e3[i]);
595 break;
597 case 0xe4: /* write test reg */
598 s->needed_bytes = 1;
599 break;
601 case 0xe7:
602 qemu_log_mask(LOG_UNIMP, "Attempt to probe for ESS (0xe7)?\n");
603 break;
605 case 0xe8: /* read test reg */
606 dsp_out_data (s, s->test_reg);
607 break;
609 case 0xf2:
610 case 0xf3:
611 dsp_out_data (s, 0xaa);
612 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
613 qemu_irq_raise (s->pic);
614 break;
616 case 0xf9:
617 s->needed_bytes = 1;
618 goto warn;
620 case 0xfa:
621 dsp_out_data (s, 0);
622 goto warn;
624 case 0xfc: /* FIXME */
625 dsp_out_data (s, 0);
626 goto warn;
628 default:
629 qemu_log_mask(LOG_UNIMP, "Unrecognized command %#x\n", cmd);
630 break;
634 if (!s->needed_bytes) {
635 ldebug ("\n");
638 exit:
639 if (!s->needed_bytes) {
640 s->cmd = -1;
642 else {
643 s->cmd = cmd;
645 return;
647 warn:
648 qemu_log_mask(LOG_UNIMP, "warning: command %#x,%d is not truly understood"
649 " yet\n", cmd, s->needed_bytes);
650 goto exit;
654 static uint16_t dsp_get_lohi (SB16State *s)
656 uint8_t hi = dsp_get_data (s);
657 uint8_t lo = dsp_get_data (s);
658 return (hi << 8) | lo;
661 static uint16_t dsp_get_hilo (SB16State *s)
663 uint8_t lo = dsp_get_data (s);
664 uint8_t hi = dsp_get_data (s);
665 return (hi << 8) | lo;
668 static void complete (SB16State *s)
670 int d0, d1, d2;
671 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
672 s->cmd, s->in_index, s->needed_bytes);
674 if (s->cmd > 0xaf && s->cmd < 0xd0) {
675 d2 = dsp_get_data (s);
676 d1 = dsp_get_data (s);
677 d0 = dsp_get_data (s);
679 if (s->cmd & 8) {
680 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
681 s->cmd, d0, d1, d2);
683 else {
684 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
685 s->cmd, d0, d1, d2);
686 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
689 else {
690 switch (s->cmd) {
691 case 0x04:
692 s->csp_mode = dsp_get_data (s);
693 s->csp_reg83r = 0;
694 s->csp_reg83w = 0;
695 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
696 break;
698 case 0x05:
699 s->csp_param = dsp_get_data (s);
700 s->csp_value = dsp_get_data (s);
701 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
702 s->csp_param,
703 s->csp_value);
704 break;
706 case 0x0e:
707 d0 = dsp_get_data (s);
708 d1 = dsp_get_data (s);
709 ldebug ("write CSP register %d <- %#x\n", d1, d0);
710 if (d1 == 0x83) {
711 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
712 s->csp_reg83[s->csp_reg83r % 4] = d0;
713 s->csp_reg83r += 1;
715 else {
716 s->csp_regs[d1] = d0;
718 break;
720 case 0x0f:
721 d0 = dsp_get_data (s);
722 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
723 d0, s->csp_regs[d0], s->csp_mode);
724 if (d0 == 0x83) {
725 ldebug ("0x83[%d] -> %#x\n",
726 s->csp_reg83w,
727 s->csp_reg83[s->csp_reg83w % 4]);
728 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
729 s->csp_reg83w += 1;
731 else {
732 dsp_out_data (s, s->csp_regs[d0]);
734 break;
736 case 0x10:
737 d0 = dsp_get_data (s);
738 dolog ("cmd 0x10 d0=%#x\n", d0);
739 break;
741 case 0x14:
742 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
743 break;
745 case 0x40:
746 s->time_const = dsp_get_data (s);
747 ldebug ("set time const %d\n", s->time_const);
748 break;
750 case 0x41:
751 case 0x42:
753 * 0x41 is documented as setting the output sample rate,
754 * and 0x42 the input sample rate, but in fact SB16 hardware
755 * seems to have only a single sample rate under the hood,
756 * and FT2 sets output freq with this (go figure). Compare:
757 * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
759 s->freq = dsp_get_hilo (s);
760 ldebug ("set freq %d\n", s->freq);
761 break;
763 case 0x48:
764 s->block_size = dsp_get_lohi (s) + 1;
765 ldebug ("set dma block len %d\n", s->block_size);
766 break;
768 case 0x74:
769 case 0x75:
770 case 0x76:
771 case 0x77:
772 /* ADPCM stuff, ignore */
773 break;
775 case 0x80:
777 int freq, samples, bytes;
778 int64_t ticks;
780 freq = s->freq > 0 ? s->freq : 11025;
781 samples = dsp_get_lohi (s) + 1;
782 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
783 ticks = muldiv64(bytes, NANOSECONDS_PER_SECOND, freq);
784 if (ticks < NANOSECONDS_PER_SECOND / 1024) {
785 qemu_irq_raise (s->pic);
787 else {
788 if (s->aux_ts) {
789 timer_mod (
790 s->aux_ts,
791 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks
795 ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
797 break;
799 case 0xe0:
800 d0 = dsp_get_data (s);
801 s->out_data_len = 0;
802 ldebug ("E0 data = %#x\n", d0);
803 dsp_out_data (s, ~d0);
804 break;
806 case 0xe2:
807 #ifdef DEBUG
808 d0 = dsp_get_data (s);
809 dolog ("E2 = %#x\n", d0);
810 #endif
811 break;
813 case 0xe4:
814 s->test_reg = dsp_get_data (s);
815 break;
817 case 0xf9:
818 d0 = dsp_get_data (s);
819 ldebug ("command 0xf9 with %#x\n", d0);
820 switch (d0) {
821 case 0x0e:
822 dsp_out_data (s, 0xff);
823 break;
825 case 0x0f:
826 dsp_out_data (s, 0x07);
827 break;
829 case 0x37:
830 dsp_out_data (s, 0x38);
831 break;
833 default:
834 dsp_out_data (s, 0x00);
835 break;
837 break;
839 default:
840 qemu_log_mask(LOG_UNIMP, "complete: unrecognized command %#x\n",
841 s->cmd);
842 return;
846 ldebug ("\n");
847 s->cmd = -1;
850 static void legacy_reset (SB16State *s)
852 struct audsettings as;
854 s->freq = 11025;
855 s->fmt_signed = 0;
856 s->fmt_bits = 8;
857 s->fmt_stereo = 0;
859 as.freq = s->freq;
860 as.nchannels = 1;
861 as.fmt = AUDIO_FORMAT_U8;
862 as.endianness = 0;
864 s->voice = AUD_open_out (
865 &s->card,
866 s->voice,
867 "sb16",
869 SB_audio_callback,
873 /* Not sure about that... */
874 /* AUD_set_active_out (s->voice, 1); */
877 static void reset (SB16State *s)
879 qemu_irq_lower (s->pic);
880 if (s->dma_auto) {
881 qemu_irq_raise (s->pic);
882 qemu_irq_lower (s->pic);
885 s->mixer_regs[0x82] = 0;
886 s->dma_auto = 0;
887 s->in_index = 0;
888 s->out_data_len = 0;
889 s->left_till_irq = 0;
890 s->needed_bytes = 0;
891 s->block_size = -1;
892 s->nzero = 0;
893 s->highspeed = 0;
894 s->v2x6 = 0;
895 s->cmd = -1;
897 dsp_out_data (s, 0xaa);
898 speaker (s, 0);
899 control (s, 0);
900 legacy_reset (s);
903 static void dsp_write(void *opaque, uint32_t nport, uint32_t val)
905 SB16State *s = opaque;
906 int iport;
908 iport = nport - s->port;
910 ldebug ("write %#x <- %#x\n", nport, val);
911 switch (iport) {
912 case 0x06:
913 switch (val) {
914 case 0x00:
915 if (s->v2x6 == 1) {
916 reset (s);
918 s->v2x6 = 0;
919 break;
921 case 0x01:
922 case 0x03: /* FreeBSD kludge */
923 s->v2x6 = 1;
924 break;
926 case 0xc6:
927 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
928 break;
930 case 0xb8: /* Panic */
931 reset (s);
932 break;
934 case 0x39:
935 dsp_out_data (s, 0x38);
936 reset (s);
937 s->v2x6 = 0x39;
938 break;
940 default:
941 s->v2x6 = val;
942 break;
944 break;
946 case 0x0c: /* write data or command | write status */
947 /* if (s->highspeed) */
948 /* break; */
950 if (s->needed_bytes == 0) {
951 command (s, val);
952 #if 0
953 if (0 == s->needed_bytes) {
954 log_dsp (s);
956 #endif
958 else {
959 if (s->in_index == sizeof (s->in2_data)) {
960 dolog ("in data overrun\n");
962 else {
963 s->in2_data[s->in_index++] = val;
964 if (s->in_index == s->needed_bytes) {
965 s->needed_bytes = 0;
966 complete (s);
967 #if 0
968 log_dsp (s);
969 #endif
973 break;
975 default:
976 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
977 break;
981 static uint32_t dsp_read(void *opaque, uint32_t nport)
983 SB16State *s = opaque;
984 int iport, retval, ack = 0;
986 iport = nport - s->port;
988 switch (iport) {
989 case 0x06: /* reset */
990 retval = 0xff;
991 break;
993 case 0x0a: /* read data */
994 if (s->out_data_len) {
995 retval = s->out_data[--s->out_data_len];
996 s->last_read_byte = retval;
998 else {
999 if (s->cmd != -1) {
1000 dolog ("empty output buffer for command %#x\n",
1001 s->cmd);
1003 retval = s->last_read_byte;
1004 /* goto error; */
1006 break;
1008 case 0x0c: /* 0 can write */
1009 retval = s->can_write ? 0 : 0x80;
1010 break;
1012 case 0x0d: /* timer interrupt clear */
1013 /* dolog ("timer interrupt clear\n"); */
1014 retval = 0;
1015 break;
1017 case 0x0e: /* data available status | irq 8 ack */
1018 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1019 if (s->mixer_regs[0x82] & 1) {
1020 ack = 1;
1021 s->mixer_regs[0x82] &= ~1;
1022 qemu_irq_lower (s->pic);
1024 break;
1026 case 0x0f: /* irq 16 ack */
1027 retval = 0xff;
1028 if (s->mixer_regs[0x82] & 2) {
1029 ack = 1;
1030 s->mixer_regs[0x82] &= ~2;
1031 qemu_irq_lower (s->pic);
1033 break;
1035 default:
1036 goto error;
1039 if (!ack) {
1040 ldebug ("read %#x -> %#x\n", nport, retval);
1043 return retval;
1045 error:
1046 dolog ("warning: dsp_read %#x error\n", nport);
1047 return 0xff;
1050 static void reset_mixer (SB16State *s)
1052 int i;
1054 memset (s->mixer_regs, 0xff, 0x7f);
1055 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1057 s->mixer_regs[0x02] = 4; /* master volume 3bits */
1058 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
1059 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
1060 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1062 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1063 s->mixer_regs[0x0c] = 0;
1065 /* d5=output filt, d1=stereo switch */
1066 s->mixer_regs[0x0e] = 0;
1068 /* voice volume L d5,d7, R d1,d3 */
1069 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1070 /* master ... */
1071 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1072 /* MIDI ... */
1073 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1075 for (i = 0x30; i < 0x48; i++) {
1076 s->mixer_regs[i] = 0x20;
1080 static void mixer_write_indexb(void *opaque, uint32_t nport, uint32_t val)
1082 SB16State *s = opaque;
1083 (void) nport;
1084 s->mixer_nreg = val;
1087 static void mixer_write_datab(void *opaque, uint32_t nport, uint32_t val)
1089 SB16State *s = opaque;
1091 (void) nport;
1092 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1094 switch (s->mixer_nreg) {
1095 case 0x00:
1096 reset_mixer (s);
1097 break;
1099 case 0x80:
1101 int irq = irq_of_magic (val);
1102 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1103 if (irq > 0) {
1104 s->irq = irq;
1107 break;
1109 case 0x81:
1111 int dma, hdma;
1113 dma = ctz32 (val & 0xf);
1114 hdma = ctz32 (val & 0xf0);
1115 if (dma != s->dma || hdma != s->hdma) {
1116 qemu_log_mask(LOG_GUEST_ERROR, "attempt to change DMA 8bit"
1117 " %d(%d), 16bit %d(%d) (val=%#x)\n", dma, s->dma,
1118 hdma, s->hdma, val);
1120 #if 0
1121 s->dma = dma;
1122 s->hdma = hdma;
1123 #endif
1125 break;
1127 case 0x82:
1128 qemu_log_mask(LOG_GUEST_ERROR, "attempt to write into IRQ status"
1129 " register (val=%#x)\n", val);
1130 return;
1132 default:
1133 if (s->mixer_nreg >= 0x80) {
1134 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1136 break;
1139 s->mixer_regs[s->mixer_nreg] = val;
1142 static uint32_t mixer_read(void *opaque, uint32_t nport)
1144 SB16State *s = opaque;
1146 (void) nport;
1147 #ifndef DEBUG_SB16_MOST
1148 if (s->mixer_nreg != 0x82) {
1149 ldebug ("mixer_read[%#x] -> %#x\n",
1150 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1152 #else
1153 ldebug ("mixer_read[%#x] -> %#x\n",
1154 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1155 #endif
1156 return s->mixer_regs[s->mixer_nreg];
1159 static int write_audio (SB16State *s, int nchan, int dma_pos,
1160 int dma_len, int len)
1162 IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma;
1163 IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
1164 int temp, net;
1165 uint8_t tmpbuf[4096];
1167 temp = len;
1168 net = 0;
1170 while (temp) {
1171 int left = dma_len - dma_pos;
1172 int copied;
1173 size_t to_copy;
1175 to_copy = MIN (temp, left);
1176 if (to_copy > sizeof (tmpbuf)) {
1177 to_copy = sizeof (tmpbuf);
1180 copied = k->read_memory(isa_dma, nchan, tmpbuf, dma_pos, to_copy);
1181 copied = AUD_write (s->voice, tmpbuf, copied);
1183 temp -= copied;
1184 dma_pos = (dma_pos + copied) % dma_len;
1185 net += copied;
1187 if (!copied) {
1188 break;
1192 return net;
1195 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1197 SB16State *s = opaque;
1198 int till, copy, written, free;
1200 if (s->block_size <= 0) {
1201 qemu_log_mask(LOG_GUEST_ERROR, "invalid block size=%d nchan=%d"
1202 " dma_pos=%d dma_len=%d\n", s->block_size, nchan,
1203 dma_pos, dma_len);
1204 return dma_pos;
1207 if (s->left_till_irq < 0) {
1208 s->left_till_irq = s->block_size;
1211 if (s->voice) {
1212 free = s->audio_free & ~s->align;
1213 if ((free <= 0) || !dma_len) {
1214 return dma_pos;
1217 else {
1218 free = dma_len;
1221 copy = free;
1222 till = s->left_till_irq;
1224 #ifdef DEBUG_SB16_MOST
1225 dolog ("pos:%06d %d till:%d len:%d\n",
1226 dma_pos, free, till, dma_len);
1227 #endif
1229 if (till <= copy) {
1230 if (s->dma_auto == 0) {
1231 copy = till;
1235 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1236 dma_pos = (dma_pos + written) % dma_len;
1237 s->left_till_irq -= written;
1239 if (s->left_till_irq <= 0) {
1240 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1241 qemu_irq_raise (s->pic);
1242 if (s->dma_auto == 0) {
1243 control (s, 0);
1244 speaker (s, 0);
1248 #ifdef DEBUG_SB16_MOST
1249 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1250 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1251 s->block_size);
1252 #endif
1254 while (s->left_till_irq <= 0) {
1255 s->left_till_irq = s->block_size + s->left_till_irq;
1258 return dma_pos;
1261 static void SB_audio_callback (void *opaque, int free)
1263 SB16State *s = opaque;
1264 s->audio_free = free;
1267 static int sb16_post_load (void *opaque, int version_id)
1269 SB16State *s = opaque;
1271 if (s->voice) {
1272 AUD_close_out (&s->card, s->voice);
1273 s->voice = NULL;
1276 if (s->dma_running) {
1277 if (s->freq) {
1278 struct audsettings as;
1280 s->audio_free = 0;
1282 as.freq = s->freq;
1283 as.nchannels = 1 << s->fmt_stereo;
1284 as.fmt = s->fmt;
1285 as.endianness = 0;
1287 s->voice = AUD_open_out (
1288 &s->card,
1289 s->voice,
1290 "sb16",
1292 SB_audio_callback,
1297 control (s, 1);
1298 speaker (s, s->speaker);
1300 return 0;
1303 static const VMStateDescription vmstate_sb16 = {
1304 .name = "sb16",
1305 .version_id = 1,
1306 .minimum_version_id = 1,
1307 .post_load = sb16_post_load,
1308 .fields = (VMStateField[]) {
1309 VMSTATE_UINT32 (irq, SB16State),
1310 VMSTATE_UINT32 (dma, SB16State),
1311 VMSTATE_UINT32 (hdma, SB16State),
1312 VMSTATE_UINT32 (port, SB16State),
1313 VMSTATE_UINT32 (ver, SB16State),
1314 VMSTATE_INT32 (in_index, SB16State),
1315 VMSTATE_INT32 (out_data_len, SB16State),
1316 VMSTATE_INT32 (fmt_stereo, SB16State),
1317 VMSTATE_INT32 (fmt_signed, SB16State),
1318 VMSTATE_INT32 (fmt_bits, SB16State),
1319 VMSTATE_UINT32 (fmt, SB16State),
1320 VMSTATE_INT32 (dma_auto, SB16State),
1321 VMSTATE_INT32 (block_size, SB16State),
1322 VMSTATE_INT32 (fifo, SB16State),
1323 VMSTATE_INT32 (freq, SB16State),
1324 VMSTATE_INT32 (time_const, SB16State),
1325 VMSTATE_INT32 (speaker, SB16State),
1326 VMSTATE_INT32 (needed_bytes, SB16State),
1327 VMSTATE_INT32 (cmd, SB16State),
1328 VMSTATE_INT32 (use_hdma, SB16State),
1329 VMSTATE_INT32 (highspeed, SB16State),
1330 VMSTATE_INT32 (can_write, SB16State),
1331 VMSTATE_INT32 (v2x6, SB16State),
1333 VMSTATE_UINT8 (csp_param, SB16State),
1334 VMSTATE_UINT8 (csp_value, SB16State),
1335 VMSTATE_UINT8 (csp_mode, SB16State),
1336 VMSTATE_UINT8 (csp_param, SB16State),
1337 VMSTATE_BUFFER (csp_regs, SB16State),
1338 VMSTATE_UINT8 (csp_index, SB16State),
1339 VMSTATE_BUFFER (csp_reg83, SB16State),
1340 VMSTATE_INT32 (csp_reg83r, SB16State),
1341 VMSTATE_INT32 (csp_reg83w, SB16State),
1343 VMSTATE_BUFFER (in2_data, SB16State),
1344 VMSTATE_BUFFER (out_data, SB16State),
1345 VMSTATE_UINT8 (test_reg, SB16State),
1346 VMSTATE_UINT8 (last_read_byte, SB16State),
1348 VMSTATE_INT32 (nzero, SB16State),
1349 VMSTATE_INT32 (left_till_irq, SB16State),
1350 VMSTATE_INT32 (dma_running, SB16State),
1351 VMSTATE_INT32 (bytes_per_second, SB16State),
1352 VMSTATE_INT32 (align, SB16State),
1354 VMSTATE_INT32 (mixer_nreg, SB16State),
1355 VMSTATE_BUFFER (mixer_regs, SB16State),
1357 VMSTATE_END_OF_LIST ()
1361 static const MemoryRegionPortio sb16_ioport_list[] = {
1362 { 4, 1, 1, .write = mixer_write_indexb },
1363 { 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
1364 { 6, 1, 1, .read = dsp_read, .write = dsp_write },
1365 { 10, 1, 1, .read = dsp_read },
1366 { 12, 1, 1, .write = dsp_write },
1367 { 12, 4, 1, .read = dsp_read },
1368 PORTIO_END_OF_LIST (),
1372 static void sb16_initfn (Object *obj)
1374 SB16State *s = SB16 (obj);
1376 s->cmd = -1;
1379 static void sb16_realizefn (DeviceState *dev, Error **errp)
1381 ISADevice *isadev = ISA_DEVICE (dev);
1382 SB16State *s = SB16 (dev);
1383 IsaDmaClass *k;
1385 s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
1386 s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
1387 if (!s->isa_dma || !s->isa_hdma) {
1388 error_setg(errp, "ISA controller does not support DMA");
1389 return;
1392 isa_init_irq (isadev, &s->pic, s->irq);
1394 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1395 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1396 s->mixer_regs[0x82] = 2 << 5;
1398 s->csp_regs[5] = 1;
1399 s->csp_regs[9] = 0xf8;
1401 reset_mixer (s);
1402 s->aux_ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, aux_timer, s);
1403 if (!s->aux_ts) {
1404 error_setg(errp, "warning: Could not create auxiliary timer");
1407 isa_register_portio_list(isadev, &s->portio_list, s->port,
1408 sb16_ioport_list, s, "sb16");
1410 k = ISADMA_GET_CLASS(s->isa_hdma);
1411 k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s);
1413 k = ISADMA_GET_CLASS(s->isa_dma);
1414 k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);
1416 s->can_write = 1;
1418 AUD_register_card ("sb16", &s->card);
1421 static Property sb16_properties[] = {
1422 DEFINE_AUDIO_PROPERTIES(SB16State, card),
1423 DEFINE_PROP_UINT32 ("version", SB16State, ver, 0x0405), /* 4.5 */
1424 DEFINE_PROP_UINT32 ("iobase", SB16State, port, 0x220),
1425 DEFINE_PROP_UINT32 ("irq", SB16State, irq, 5),
1426 DEFINE_PROP_UINT32 ("dma", SB16State, dma, 1),
1427 DEFINE_PROP_UINT32 ("dma16", SB16State, hdma, 5),
1428 DEFINE_PROP_END_OF_LIST (),
1431 static void sb16_class_initfn (ObjectClass *klass, void *data)
1433 DeviceClass *dc = DEVICE_CLASS (klass);
1435 dc->realize = sb16_realizefn;
1436 set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
1437 dc->desc = "Creative Sound Blaster 16";
1438 dc->vmsd = &vmstate_sb16;
1439 device_class_set_props(dc, sb16_properties);
1442 static const TypeInfo sb16_info = {
1443 .name = TYPE_SB16,
1444 .parent = TYPE_ISA_DEVICE,
1445 .instance_size = sizeof (SB16State),
1446 .instance_init = sb16_initfn,
1447 .class_init = sb16_class_initfn,
1450 static void sb16_register_types (void)
1452 type_register_static (&sb16_info);
1453 deprecated_register_soundhw("sb16", "Creative Sound Blaster 16",
1454 1, TYPE_SB16);
1457 type_init (sb16_register_types)