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