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