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