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