]> git.proxmox.com Git - qemu.git/blob - hw/sb16.c
audio merge (malc)
[qemu.git] / hw / sb16.c
1 /*
2 * QEMU Soundblaster 16 emulation
3 *
4 * Copyright (c) 2003-2004 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 "vl.h"
25
26 /* #define DEBUG */
27 #define AUDIO_CAP "sb16"
28 #include "audio/audio.h"
29
30 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
31
32 /* #define DEBUG_SB16_MOST */
33
34 #define IO_READ_PROTO(name) \
35 uint32_t name (void *opaque, uint32_t nport)
36 #define IO_WRITE_PROTO(name) \
37 void name (void *opaque, uint32_t nport, uint32_t val)
38
39 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
40
41 static struct {
42 int ver_lo;
43 int ver_hi;
44 int irq;
45 int dma;
46 int hdma;
47 int port;
48 } conf = {5, 4, 5, 1, 5, 0x220};
49
50 typedef struct SB16State {
51 int irq;
52 int dma;
53 int hdma;
54 int port;
55 int ver;
56
57 int in_index;
58 int out_data_len;
59 int fmt_stereo;
60 int fmt_signed;
61 int fmt_bits;
62 audfmt_e fmt;
63 int dma_auto;
64 int block_size;
65 int fifo;
66 int freq;
67 int time_const;
68 int speaker;
69 int needed_bytes;
70 int cmd;
71 int use_hdma;
72 int highspeed;
73 int can_write;
74
75 int v2x6;
76
77 uint8_t csp_param;
78 uint8_t csp_value;
79 uint8_t csp_mode;
80 uint8_t csp_regs[256];
81 uint8_t csp_index;
82 uint8_t csp_reg83[4];
83 int csp_reg83r;
84 int csp_reg83w;
85
86 uint8_t in2_data[10];
87 uint8_t out_data[50];
88 uint8_t test_reg;
89 uint8_t last_read_byte;
90 int nzero;
91
92 int left_till_irq;
93
94 int dma_running;
95 int bytes_per_second;
96 int align;
97 SWVoice *voice;
98
99 QEMUTimer *ts, *aux_ts;
100 /* mixer state */
101 int mixer_nreg;
102 uint8_t mixer_regs[256];
103 } SB16State;
104
105 /* XXX: suppress that and use a context */
106 static struct SB16State dsp;
107
108 static int magic_of_irq (int irq)
109 {
110 switch (irq) {
111 case 5:
112 return 2;
113 case 7:
114 return 4;
115 case 9:
116 return 1;
117 case 10:
118 return 8;
119 default:
120 dolog ("bad irq %d\n", irq);
121 return 2;
122 }
123 }
124
125 static int irq_of_magic (int magic)
126 {
127 switch (magic) {
128 case 1:
129 return 9;
130 case 2:
131 return 5;
132 case 4:
133 return 7;
134 case 8:
135 return 10;
136 default:
137 dolog ("bad irq magic %d\n", magic);
138 return -1;
139 }
140 }
141
142 #if 0
143 static void log_dsp (SB16State *dsp)
144 {
145 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
146 dsp->fmt_stereo ? "Stereo" : "Mono",
147 dsp->fmt_signed ? "Signed" : "Unsigned",
148 dsp->fmt_bits,
149 dsp->dma_auto ? "Auto" : "Single",
150 dsp->block_size,
151 dsp->freq,
152 dsp->time_const,
153 dsp->speaker);
154 }
155 #endif
156
157 static void speaker (SB16State *s, int on)
158 {
159 s->speaker = on;
160 /* AUD_enable (s->voice, on); */
161 }
162
163 static void control (SB16State *s, int hold)
164 {
165 int dma = s->use_hdma ? s->hdma : s->dma;
166 s->dma_running = hold;
167
168 ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
169
170 if (hold) {
171 DMA_hold_DREQ (dma);
172 AUD_enable (s->voice, 1);
173 }
174 else {
175 DMA_release_DREQ (dma);
176 AUD_enable (s->voice, 0);
177 }
178 }
179
180 static void aux_timer (void *opaque)
181 {
182 SB16State *s = opaque;
183 s->can_write = 1;
184 pic_set_irq (s->irq, 1);
185 }
186
187 #define DMA8_AUTO 1
188 #define DMA8_HIGH 2
189
190 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
191 {
192 s->fmt = AUD_FMT_U8;
193 s->use_hdma = 0;
194 s->fmt_bits = 8;
195 s->fmt_signed = 0;
196 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
197 if (-1 == s->time_const) {
198 s->freq = 11025;
199 }
200 else {
201 int tmp = (256 - s->time_const);
202 s->freq = (1000000 + (tmp / 2)) / tmp;
203 }
204
205 if (-1 != dma_len)
206 s->block_size = dma_len + 1;
207
208 s->freq >>= s->fmt_stereo;
209 s->left_till_irq = s->block_size;
210 s->bytes_per_second = (s->freq << s->fmt_stereo);
211 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
212 s->dma_auto = (mask & DMA8_AUTO) != 0;
213 s->align = (1 << s->fmt_stereo) - 1;
214
215 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
216 "dma %d, auto %d, fifo %d, high %d\n",
217 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
218 s->block_size, s->dma_auto, s->fifo, s->highspeed);
219
220 if (s->freq)
221 s->voice = AUD_open (s->voice, "sb16", s->freq,
222 1 << s->fmt_stereo, s->fmt);
223
224 control (s, 1);
225 speaker (s, 1);
226 }
227
228 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
229 {
230 s->use_hdma = cmd < 0xc0;
231 s->fifo = (cmd >> 1) & 1;
232 s->dma_auto = (cmd >> 2) & 1;
233 s->fmt_signed = (d0 >> 4) & 1;
234 s->fmt_stereo = (d0 >> 5) & 1;
235
236 switch (cmd >> 4) {
237 case 11:
238 s->fmt_bits = 16;
239 break;
240
241 case 12:
242 s->fmt_bits = 8;
243 break;
244 }
245
246 if (-1 != s->time_const) {
247 #if 1
248 int tmp = 256 - s->time_const;
249 s->freq = (1000000 + (tmp / 2)) / tmp;
250 #else
251 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
252 s->freq = 1000000 / ((255 - s->time_const));
253 #endif
254 s->time_const = -1;
255 }
256
257 s->block_size = dma_len + 1;
258 s->block_size <<= (s->fmt_bits == 16);
259 if (!s->dma_auto) /* Miles Sound System ? */
260 s->block_size <<= s->fmt_stereo;
261
262 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
263 "dma %d, auto %d, fifo %d, high %d\n",
264 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
265 s->block_size, s->dma_auto, s->fifo, s->highspeed);
266
267 if (16 == s->fmt_bits) {
268 if (s->fmt_signed) {
269 s->fmt = AUD_FMT_S16;
270 }
271 else {
272 s->fmt = AUD_FMT_U16;
273 }
274 }
275 else {
276 if (s->fmt_signed) {
277 s->fmt = AUD_FMT_S8;
278 }
279 else {
280 s->fmt = AUD_FMT_U8;
281 }
282 }
283
284 s->left_till_irq = s->block_size;
285
286 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
287 s->highspeed = 0;
288 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
289
290 if (s->freq)
291 s->voice = AUD_open (s->voice, "sb16", s->freq,
292 1 << s->fmt_stereo, s->fmt);
293
294 control (s, 1);
295 speaker (s, 1);
296 }
297
298 static inline void dsp_out_data (SB16State *s, uint8_t val)
299 {
300 ldebug ("outdata %#x\n", val);
301 if (s->out_data_len < sizeof (s->out_data))
302 s->out_data[s->out_data_len++] = val;
303 }
304
305 static inline uint8_t dsp_get_data (SB16State *s)
306 {
307 if (s->in_index)
308 return s->in2_data[--s->in_index];
309 else {
310 dolog ("buffer underflow\n");
311 return 0;
312 }
313 }
314
315 static void command (SB16State *s, uint8_t cmd)
316 {
317 ldebug ("command %#x\n", cmd);
318
319 if (cmd > 0xaf && cmd < 0xd0) {
320 if (cmd & 8) {
321 dolog ("ADC not yet supported (command %#x)\n", cmd);
322 }
323
324 switch (cmd >> 4) {
325 case 11:
326 case 12:
327 break;
328 default:
329 dolog ("%#x wrong bits\n", cmd);
330 }
331 s->needed_bytes = 3;
332 }
333 else {
334 switch (cmd) {
335 case 0x03:
336 dsp_out_data (s, 0x10); /* s->csp_param); */
337 goto warn;
338
339 case 0x04:
340 s->needed_bytes = 1;
341 goto warn;
342
343 case 0x05:
344 s->needed_bytes = 2;
345 goto warn;
346
347 case 0x08:
348 /* __asm__ ("int3"); */
349 goto warn;
350
351 case 0x0e:
352 s->needed_bytes = 2;
353 goto warn;
354
355 case 0x09:
356 dsp_out_data (s, 0xf8);
357 goto warn;
358
359 case 0x0f:
360 s->needed_bytes = 1;
361 goto warn;
362
363 case 0x10:
364 s->needed_bytes = 1;
365 goto warn;
366
367 case 0x14:
368 s->needed_bytes = 2;
369 s->block_size = 0;
370 break;
371
372 case 0x20: /* Direct ADC, Juice/PL */
373 dsp_out_data (s, 0xff);
374 goto warn;
375
376 case 0x35:
377 dolog ("MIDI command(0x35) not implemented\n");
378 break;
379
380 case 0x40:
381 s->freq = -1;
382 s->time_const = -1;
383 s->needed_bytes = 1;
384 break;
385
386 case 0x41:
387 s->freq = -1;
388 s->time_const = -1;
389 s->needed_bytes = 2;
390 break;
391
392 case 0x42:
393 s->freq = -1;
394 s->time_const = -1;
395 s->needed_bytes = 2;
396 goto warn;
397
398 case 0x45:
399 dsp_out_data (s, 0xaa);
400 goto warn;
401
402 case 0x47: /* Continue Auto-Initialize DMA 16bit */
403 break;
404
405 case 0x48:
406 s->needed_bytes = 2;
407 break;
408
409 case 0x80:
410 s->needed_bytes = 2;
411 break;
412
413 case 0x90:
414 case 0x91:
415 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
416 break;
417
418 case 0xd0: /* halt DMA operation. 8bit */
419 control (s, 0);
420 break;
421
422 case 0xd1: /* speaker on */
423 speaker (s, 1);
424 break;
425
426 case 0xd3: /* speaker off */
427 speaker (s, 0);
428 break;
429
430 case 0xd4: /* continue DMA operation. 8bit */
431 control (s, 1);
432 break;
433
434 case 0xd5: /* halt DMA operation. 16bit */
435 control (s, 0);
436 break;
437
438 case 0xd6: /* continue DMA operation. 16bit */
439 control (s, 1);
440 break;
441
442 case 0xd9: /* exit auto-init DMA after this block. 16bit */
443 s->dma_auto = 0;
444 break;
445
446 case 0xda: /* exit auto-init DMA after this block. 8bit */
447 s->dma_auto = 0;
448 break;
449
450 case 0xe0:
451 s->needed_bytes = 1;
452 goto warn;
453
454 case 0xe1:
455 dsp_out_data (s, s->ver & 0xff);
456 dsp_out_data (s, s->ver >> 8);
457 break;
458
459 case 0xe2:
460 s->needed_bytes = 1;
461 goto warn;
462
463 case 0xe3:
464 {
465 int i;
466 for (i = sizeof (e3) - 1; i >= 0; --i)
467 dsp_out_data (s, e3[i]);
468 }
469 break;
470
471 case 0xe4: /* write test reg */
472 s->needed_bytes = 1;
473 break;
474
475 case 0xe7:
476 dolog ("Attempt to probe for ESS (0xe7)?\n");
477 return;
478
479 case 0xe8: /* read test reg */
480 dsp_out_data (s, s->test_reg);
481 break;
482
483 case 0xf2:
484 case 0xf3:
485 dsp_out_data (s, 0xaa);
486 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
487 pic_set_irq (s->irq, 1);
488 break;
489
490 case 0xf9:
491 s->needed_bytes = 1;
492 goto warn;
493
494 case 0xfa:
495 dsp_out_data (s, 0);
496 goto warn;
497
498 case 0xfc: /* FIXME */
499 dsp_out_data (s, 0);
500 goto warn;
501
502 default:
503 dolog ("unrecognized command %#x\n", cmd);
504 return;
505 }
506 }
507
508 s->cmd = cmd;
509 if (!s->needed_bytes)
510 ldebug ("\n");
511 return;
512
513 warn:
514 dolog ("warning command %#x,%d is not trully understood yet\n",
515 cmd, s->needed_bytes);
516 s->cmd = cmd;
517 return;
518 }
519
520 static uint16_t dsp_get_lohi (SB16State *s)
521 {
522 uint8_t hi = dsp_get_data (s);
523 uint8_t lo = dsp_get_data (s);
524 return (hi << 8) | lo;
525 }
526
527 static uint16_t dsp_get_hilo (SB16State *s)
528 {
529 uint8_t lo = dsp_get_data (s);
530 uint8_t hi = dsp_get_data (s);
531 return (hi << 8) | lo;
532 }
533
534 static void complete (SB16State *s)
535 {
536 int d0, d1, d2;
537 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
538 s->cmd, s->in_index, s->needed_bytes);
539
540 if (s->cmd > 0xaf && s->cmd < 0xd0) {
541 d2 = dsp_get_data (s);
542 d1 = dsp_get_data (s);
543 d0 = dsp_get_data (s);
544
545 if (s->cmd & 8) {
546 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
547 s->cmd, d0, d1, d2);
548 }
549 else {
550 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
551 s->cmd, d0, d1, d2);
552 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
553 }
554 }
555 else {
556 switch (s->cmd) {
557 case 0x04:
558 s->csp_mode = dsp_get_data (s);
559 s->csp_reg83r = 0;
560 s->csp_reg83w = 0;
561 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
562 break;
563
564 case 0x05:
565 s->csp_param = dsp_get_data (s);
566 s->csp_value = dsp_get_data (s);
567 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
568 s->csp_param,
569 s->csp_value);
570 break;
571
572 case 0x0e:
573 d0 = dsp_get_data (s);
574 d1 = dsp_get_data (s);
575 ldebug ("write CSP register %d <- %#x\n", d1, d0);
576 if (d1 == 0x83) {
577 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
578 s->csp_reg83[s->csp_reg83r % 4] = d0;
579 s->csp_reg83r += 1;
580 }
581 else
582 s->csp_regs[d1] = d0;
583 break;
584
585 case 0x0f:
586 d0 = dsp_get_data (s);
587 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
588 d0, s->csp_regs[d0], s->csp_mode);
589 if (d0 == 0x83) {
590 ldebug ("0x83[%d] -> %#x\n",
591 s->csp_reg83w,
592 s->csp_reg83[s->csp_reg83w % 4]);
593 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
594 s->csp_reg83w += 1;
595 }
596 else
597 dsp_out_data (s, s->csp_regs[d0]);
598 break;
599
600 case 0x10:
601 d0 = dsp_get_data (s);
602 dolog ("cmd 0x10 d0=%#x\n", d0);
603 break;
604
605 case 0x14:
606 dma_cmd8 (s, 0, dsp_get_lohi (s));
607 /* s->can_write = 0; */
608 /* qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + (ticks_per_sec * 320) / 1000000); */
609 break;
610
611 case 0x40:
612 s->time_const = dsp_get_data (s);
613 ldebug ("set time const %d\n", s->time_const);
614 break;
615
616 case 0x42: /* FT2 sets output freq with this, go figure */
617 dolog ("cmd 0x42 might not do what it think it should\n");
618
619 case 0x41:
620 s->freq = dsp_get_hilo (s);
621 ldebug ("set freq %d\n", s->freq);
622 break;
623
624 case 0x48:
625 s->block_size = dsp_get_lohi (s);
626 /* s->highspeed = 1; */
627 ldebug ("set dma block len %d\n", s->block_size);
628 break;
629
630 case 0x80:
631 {
632 int samples, bytes;
633 int64_t ticks;
634
635 if (-1 == s->freq)
636 s->freq = 11025;
637 samples = dsp_get_lohi (s);
638 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
639 ticks = ticks_per_sec / (s->freq / bytes);
640 if (ticks < ticks_per_sec / 1024)
641 pic_set_irq (s->irq, 1);
642 else
643 qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
644 ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
645 }
646 break;
647
648 case 0xe0:
649 d0 = dsp_get_data (s);
650 s->out_data_len = 0;
651 ldebug ("E0 data = %#x\n", d0);
652 dsp_out_data(s, ~d0);
653 break;
654
655 case 0xe2:
656 d0 = dsp_get_data (s);
657 dolog ("E2 = %#x\n", d0);
658 break;
659
660 case 0xe4:
661 s->test_reg = dsp_get_data (s);
662 break;
663
664 case 0xf9:
665 d0 = dsp_get_data (s);
666 ldebug ("command 0xf9 with %#x\n", d0);
667 switch (d0) {
668 case 0x0e:
669 dsp_out_data (s, 0xff);
670 break;
671
672 case 0x0f:
673 dsp_out_data (s, 0x07);
674 break;
675
676 case 0x37:
677 dsp_out_data (s, 0x38);
678 break;
679
680 default:
681 dsp_out_data (s, 0x00);
682 break;
683 }
684 break;
685
686 default:
687 dolog ("complete: unrecognized command %#x\n", s->cmd);
688 return;
689 }
690 }
691
692 ldebug ("\n");
693 s->cmd = -1;
694 return;
695 }
696
697 static void reset (SB16State *s)
698 {
699 pic_set_irq (s->irq, 0);
700 if (s->dma_auto) {
701 pic_set_irq (s->irq, 1);
702 pic_set_irq (s->irq, 0);
703 }
704
705 s->mixer_regs[0x82] = 0;
706 s->dma_auto = 0;
707 s->in_index = 0;
708 s->out_data_len = 0;
709 s->left_till_irq = 0;
710 s->needed_bytes = 0;
711 s->block_size = -1;
712 s->nzero = 0;
713 s->highspeed = 0;
714 s->v2x6 = 0;
715
716 dsp_out_data(s, 0xaa);
717 speaker (s, 0);
718 control (s, 0);
719 }
720
721 static IO_WRITE_PROTO (dsp_write)
722 {
723 SB16State *s = opaque;
724 int iport;
725
726 iport = nport - s->port;
727
728 ldebug ("write %#x <- %#x\n", nport, val);
729 switch (iport) {
730 case 0x06:
731 switch (val) {
732 case 0x00:
733 if (s->v2x6 == 1) {
734 if (0 && s->highspeed) {
735 s->highspeed = 0;
736 pic_set_irq (s->irq, 0);
737 control (s, 0);
738 }
739 else
740 reset (s);
741 }
742 s->v2x6 = 0;
743 break;
744
745 case 0x01:
746 case 0x03: /* FreeBSD kludge */
747 s->v2x6 = 1;
748 break;
749
750 case 0xc6:
751 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
752 break;
753
754 case 0xb8: /* Panic */
755 reset (s);
756 break;
757
758 case 0x39:
759 dsp_out_data (s, 0x38);
760 reset (s);
761 s->v2x6 = 0x39;
762 break;
763
764 default:
765 s->v2x6 = val;
766 break;
767 }
768 break;
769
770 case 0x0c: /* write data or command | write status */
771 /* if (s->highspeed) */
772 /* break; */
773
774 if (0 == s->needed_bytes) {
775 command (s, val);
776 #if 0
777 if (0 == s->needed_bytes) {
778 log_dsp (s);
779 }
780 #endif
781 }
782 else {
783 if (s->in_index == sizeof (s->in2_data)) {
784 dolog ("in data overrun\n");
785 }
786 else {
787 s->in2_data[s->in_index++] = val;
788 if (s->in_index == s->needed_bytes) {
789 s->needed_bytes = 0;
790 complete (s);
791 #if 0
792 log_dsp (s);
793 #endif
794 }
795 }
796 }
797 break;
798
799 default:
800 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
801 break;
802 }
803 }
804
805 static IO_READ_PROTO (dsp_read)
806 {
807 SB16State *s = opaque;
808 int iport, retval, ack = 0;
809
810 iport = nport - s->port;
811
812 switch (iport) {
813 case 0x06: /* reset */
814 retval = 0xff;
815 break;
816
817 case 0x0a: /* read data */
818 if (s->out_data_len) {
819 retval = s->out_data[--s->out_data_len];
820 s->last_read_byte = retval;
821 }
822 else {
823 dolog ("empty output buffer\n");
824 retval = s->last_read_byte;
825 /* goto error; */
826 }
827 break;
828
829 case 0x0c: /* 0 can write */
830 retval = s->can_write ? 0 : 0x80;
831 break;
832
833 case 0x0d: /* timer interrupt clear */
834 /* dolog ("timer interrupt clear\n"); */
835 retval = 0;
836 break;
837
838 case 0x0e: /* data available status | irq 8 ack */
839 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
840 if (s->mixer_regs[0x82] & 1) {
841 ack = 1;
842 s->mixer_regs[0x82] &= 1;
843 pic_set_irq (s->irq, 0);
844 }
845 break;
846
847 case 0x0f: /* irq 16 ack */
848 retval = 0xff;
849 if (s->mixer_regs[0x82] & 2) {
850 ack = 1;
851 s->mixer_regs[0x82] &= 2;
852 pic_set_irq (s->irq, 0);
853 }
854 break;
855
856 default:
857 goto error;
858 }
859
860 if (!ack)
861 ldebug ("read %#x -> %#x\n", nport, retval);
862
863 return retval;
864
865 error:
866 dolog ("WARNING dsp_read %#x error\n", nport);
867 return 0xff;
868 }
869
870 static void reset_mixer (SB16State *s)
871 {
872 int i;
873
874 memset (s->mixer_regs, 0xff, 0x7f);
875 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
876
877 s->mixer_regs[0x02] = 4; /* master volume 3bits */
878 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
879 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
880 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
881
882 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
883 s->mixer_regs[0x0c] = 0;
884
885 /* d5=output filt, d1=stereo switch */
886 s->mixer_regs[0x0e] = 0;
887
888 /* voice volume L d5,d7, R d1,d3 */
889 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
890 /* master ... */
891 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
892 /* MIDI ... */
893 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
894
895 for (i = 0x30; i < 0x48; i++) {
896 s->mixer_regs[i] = 0x20;
897 }
898 }
899
900 static IO_WRITE_PROTO(mixer_write_indexb)
901 {
902 SB16State *s = opaque;
903 s->mixer_nreg = val;
904 }
905
906 static IO_WRITE_PROTO(mixer_write_datab)
907 {
908 SB16State *s = opaque;
909
910 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
911 if (s->mixer_nreg > sizeof (s->mixer_regs))
912 return;
913
914 switch (s->mixer_nreg) {
915 case 0x00:
916 reset_mixer (s);
917 break;
918
919 case 0x80:
920 {
921 int irq = irq_of_magic (val);
922 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
923 if (irq > 0)
924 s->irq = irq;
925 }
926 break;
927
928 case 0x81:
929 {
930 int dma, hdma;
931
932 dma = lsbindex (val & 0xf);
933 hdma = lsbindex (val & 0xf0);
934 dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
935 dma, hdma, val);
936 #if 0
937 s->dma = dma;
938 s->hdma = hdma;
939 #endif
940 }
941 break;
942
943 case 0x82:
944 dolog ("attempt to write into IRQ status register (val=%#x)\n",
945 val);
946 return;
947
948 default:
949 if (s->mixer_nreg >= 0x80)
950 dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
951 break;
952 }
953
954 s->mixer_regs[s->mixer_nreg] = val;
955 }
956
957 static IO_WRITE_PROTO(mixer_write_indexw)
958 {
959 mixer_write_indexb (opaque, nport, val & 0xff);
960 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
961 }
962
963 static IO_READ_PROTO(mixer_read)
964 {
965 SB16State *s = opaque;
966 ldebug ("mixer_read[%#x] -> %#x\n",
967 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
968 return s->mixer_regs[s->mixer_nreg];
969 }
970
971 static int write_audio (SB16State *s, int nchan, int dma_pos,
972 int dma_len, int len)
973 {
974 int temp, net;
975 uint8_t tmpbuf[4096];
976
977 temp = len;
978 net = 0;
979
980 while (temp) {
981 int left = dma_len - dma_pos;
982 int to_copy, copied;
983
984 to_copy = audio_MIN (temp, left);
985 if (to_copy > sizeof(tmpbuf))
986 to_copy = sizeof(tmpbuf);
987
988 copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
989 copied = AUD_write (s->voice, tmpbuf, copied);
990
991 temp -= copied;
992 dma_pos = (dma_pos + copied) % dma_len;
993 net += copied;
994
995 if (!copied)
996 break;
997 }
998
999 return net;
1000 }
1001
1002 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1003 {
1004 SB16State *s = opaque;
1005 int free, rfree, till, copy, written, elapsed;
1006
1007 if (s->left_till_irq < 0) {
1008 s->left_till_irq = s->block_size;
1009 }
1010
1011 elapsed = AUD_calc_elapsed (s->voice);
1012 free = elapsed;/* AUD_get_free (s->voice); */
1013 rfree = free;
1014 free = audio_MIN (free, elapsed) & ~s->align;
1015
1016 if ((free <= 0) || !dma_len) {
1017 return dma_pos;
1018 }
1019
1020 copy = free;
1021 till = s->left_till_irq;
1022
1023 #ifdef DEBUG_SB16_MOST
1024 dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
1025 dma_pos, free, AUD_get_free (s->voice), till, dma_len);
1026 #endif
1027
1028 if (till <= copy) {
1029 if (0 == s->dma_auto) {
1030 copy = till;
1031 }
1032 }
1033
1034 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1035 dma_pos = (dma_pos + written) % dma_len;
1036 s->left_till_irq -= written;
1037
1038 if (s->left_till_irq <= 0) {
1039 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1040 pic_set_irq (s->irq, 1);
1041 if (0 == s->dma_auto) {
1042 control (s, 0);
1043 speaker (s, 0);
1044 }
1045 }
1046
1047 #ifdef DEBUG_SB16_MOST
1048 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
1049 dma_pos, free, dma_len, s->left_till_irq, copy, s->block_size);
1050 #endif
1051
1052 while (s->left_till_irq <= 0) {
1053 s->left_till_irq = s->block_size + s->left_till_irq;
1054 }
1055
1056 AUD_adjust (s->voice, written);
1057 return dma_pos;
1058 }
1059
1060 void SB_timer (void *opaque)
1061 {
1062 SB16State *s = opaque;
1063 AUD_run ();
1064 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1065 }
1066
1067 static void SB_save (QEMUFile *f, void *opaque)
1068 {
1069 SB16State *s = opaque;
1070
1071 qemu_put_be32s (f, &s->irq);
1072 qemu_put_be32s (f, &s->dma);
1073 qemu_put_be32s (f, &s->hdma);
1074 qemu_put_be32s (f, &s->port);
1075 qemu_put_be32s (f, &s->ver);
1076 qemu_put_be32s (f, &s->in_index);
1077 qemu_put_be32s (f, &s->out_data_len);
1078 qemu_put_be32s (f, &s->fmt_stereo);
1079 qemu_put_be32s (f, &s->fmt_signed);
1080 qemu_put_be32s (f, &s->fmt_bits);
1081 qemu_put_be32s (f, &s->fmt);
1082 qemu_put_be32s (f, &s->dma_auto);
1083 qemu_put_be32s (f, &s->block_size);
1084 qemu_put_be32s (f, &s->fifo);
1085 qemu_put_be32s (f, &s->freq);
1086 qemu_put_be32s (f, &s->time_const);
1087 qemu_put_be32s (f, &s->speaker);
1088 qemu_put_be32s (f, &s->needed_bytes);
1089 qemu_put_be32s (f, &s->cmd);
1090 qemu_put_be32s (f, &s->use_hdma);
1091 qemu_put_be32s (f, &s->highspeed);
1092 qemu_put_be32s (f, &s->can_write);
1093 qemu_put_be32s (f, &s->v2x6);
1094
1095 qemu_put_8s (f, &s->csp_param);
1096 qemu_put_8s (f, &s->csp_value);
1097 qemu_put_8s (f, &s->csp_mode);
1098 qemu_put_8s (f, &s->csp_param);
1099 qemu_put_buffer (f, s->csp_regs, 256);
1100 qemu_put_8s (f, &s->csp_index);
1101 qemu_put_buffer (f, s->csp_reg83, 4);
1102 qemu_put_be32s (f, &s->csp_reg83r);
1103 qemu_put_be32s (f, &s->csp_reg83w);
1104
1105 qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1106 qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1107 qemu_put_8s (f, &s->test_reg);
1108 qemu_put_8s (f, &s->last_read_byte);
1109
1110 qemu_put_be32s (f, &s->nzero);
1111 qemu_put_be32s (f, &s->left_till_irq);
1112 qemu_put_be32s (f, &s->dma_running);
1113 qemu_put_be32s (f, &s->bytes_per_second);
1114 qemu_put_be32s (f, &s->align);
1115
1116 qemu_put_be32s (f, &s->mixer_nreg);
1117 qemu_put_buffer (f, s->mixer_regs, 256);
1118 }
1119
1120 static int SB_load (QEMUFile *f, void *opaque, int version_id)
1121 {
1122 SB16State *s = opaque;
1123
1124 if (version_id != 1)
1125 return -EINVAL;
1126
1127 qemu_get_be32s (f, &s->irq);
1128 qemu_get_be32s (f, &s->dma);
1129 qemu_get_be32s (f, &s->hdma);
1130 qemu_get_be32s (f, &s->port);
1131 qemu_get_be32s (f, &s->ver);
1132 qemu_get_be32s (f, &s->in_index);
1133 qemu_get_be32s (f, &s->out_data_len);
1134 qemu_get_be32s (f, &s->fmt_stereo);
1135 qemu_get_be32s (f, &s->fmt_signed);
1136 qemu_get_be32s (f, &s->fmt_bits);
1137 qemu_get_be32s (f, &s->fmt);
1138 qemu_get_be32s (f, &s->dma_auto);
1139 qemu_get_be32s (f, &s->block_size);
1140 qemu_get_be32s (f, &s->fifo);
1141 qemu_get_be32s (f, &s->freq);
1142 qemu_get_be32s (f, &s->time_const);
1143 qemu_get_be32s (f, &s->speaker);
1144 qemu_get_be32s (f, &s->needed_bytes);
1145 qemu_get_be32s (f, &s->cmd);
1146 qemu_get_be32s (f, &s->use_hdma);
1147 qemu_get_be32s (f, &s->highspeed);
1148 qemu_get_be32s (f, &s->can_write);
1149 qemu_get_be32s (f, &s->v2x6);
1150
1151 qemu_get_8s (f, &s->csp_param);
1152 qemu_get_8s (f, &s->csp_value);
1153 qemu_get_8s (f, &s->csp_mode);
1154 qemu_get_8s (f, &s->csp_param);
1155 qemu_get_buffer (f, s->csp_regs, 256);
1156 qemu_get_8s (f, &s->csp_index);
1157 qemu_get_buffer (f, s->csp_reg83, 4);
1158 qemu_get_be32s (f, &s->csp_reg83r);
1159 qemu_get_be32s (f, &s->csp_reg83w);
1160
1161 qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1162 qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1163 qemu_get_8s (f, &s->test_reg);
1164 qemu_get_8s (f, &s->last_read_byte);
1165
1166 qemu_get_be32s (f, &s->nzero);
1167 qemu_get_be32s (f, &s->left_till_irq);
1168 qemu_get_be32s (f, &s->dma_running);
1169 qemu_get_be32s (f, &s->bytes_per_second);
1170 qemu_get_be32s (f, &s->align);
1171
1172 qemu_get_be32s (f, &s->mixer_nreg);
1173 qemu_get_buffer (f, s->mixer_regs, 256);
1174
1175 if (s->voice)
1176 AUD_reset (s->voice);
1177
1178 if (s->dma_running) {
1179 if (s->freq)
1180 s->voice = AUD_open (s->voice, "sb16", s->freq,
1181 1 << s->fmt_stereo, s->fmt);
1182
1183 control (s, 1);
1184 speaker (s, s->speaker);
1185 }
1186 return 0;
1187 }
1188
1189 void SB16_init (void)
1190 {
1191 SB16State *s = &dsp;
1192 int i;
1193 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1194 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1195
1196 s->ts = qemu_new_timer (vm_clock, SB_timer, s);
1197 if (!s->ts)
1198 return;
1199
1200 s->irq = conf.irq;
1201 s->dma = conf.dma;
1202 s->hdma = conf.hdma;
1203 s->port = conf.port;
1204 s->ver = conf.ver_lo | (conf.ver_hi << 8);
1205
1206 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1207 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1208 s->mixer_regs[0x82] = 2 << 5;
1209
1210 s->csp_regs[5] = 1;
1211 s->csp_regs[9] = 0xf8;
1212
1213 reset_mixer (s);
1214 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1215 if (!s->aux_ts)
1216 return;
1217
1218 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1219 register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1220 }
1221
1222 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1223 register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1224 }
1225
1226 register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1227 register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1228 register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1229 register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1230
1231 DMA_register_channel (s->hdma, SB_read_DMA, s);
1232 DMA_register_channel (s->dma, SB_read_DMA, s);
1233 s->can_write = 1;
1234
1235 qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1236 register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1237 }