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