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