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