]> Git Repo - qemu.git/blob - hw/audio/sb16.c
Merge remote-tracking branch 'remotes/berrange/tags/qcrypto-next-pull-request' into...
[qemu.git] / hw / audio / 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 "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 /* #define DEBUG */
38 /* #define DEBUG_SB16_MOST */
39
40 #ifdef DEBUG
41 #define ldebug(...) dolog (__VA_ARGS__)
42 #else
43 #define ldebug(...)
44 #endif
45
46 static 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
51 typedef 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     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     PortioList portio_list;
112 } SB16State;
113
114 static void SB_audio_callback (void *opaque, int free);
115
116 static 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
133 static 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
151 static 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
165 static void speaker (SB16State *s, int on)
166 {
167     s->speaker = on;
168     /* AUD_enable (s->voice, on); */
169 }
170
171 static 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
190 static 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
200 static 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
225 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
226 {
227     s->fmt = AUD_FMT_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         /* This is apparently the only way to make both Act1/PL
246            and SecondReality/FC work
247
248            Act1 sets block size via command 0x48 and it's an odd number
249            SR does the same with even number
250            Both use stereo, and Creatives own documentation states that
251            0x48 sets block size in bytes less one.. go figure */
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     /* s->highspeed = (mask & DMA8_HIGH) != 0; */
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
276 static 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         /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
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         /* It is clear that for DOOM and auto-init this value
309            shouldn't take stereo into account, while Miles Sound Systems
310            setsound.exe with single transfer mode wouldn't work without it
311            wonders of SB16 yet again */
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 = AUD_FMT_S16;
323         }
324         else {
325             s->fmt = AUD_FMT_U16;
326         }
327     }
328     else {
329         if (s->fmt_signed) {
330             s->fmt = AUD_FMT_S8;
331         }
332         else {
333             s->fmt = AUD_FMT_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
371 static 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
379 static 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
390 static 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); /* s->csp_param); */
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             /* __asm__ ("int3"); */
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:              /* Auto-Initialize DMA DAC, 8-bit */
451             dma_cmd8 (s, DMA8_AUTO, -1);
452             break;
453
454         case 0x20:              /* Direct ADC, Juice/PL */
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:                /* Continue Auto-Initialize DMA 16bit */
485             break;
486
487         case 0x48:
488             s->needed_bytes = 2;
489             break;
490
491         case 0x74:
492             s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
493             qemu_log_mask(LOG_UNIMP, "0x75 - DMA DAC, 4-bit ADPCM not"
494                           " implemented\n");
495             break;
496
497         case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
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:              /* DMA DAC, 2.6-bit ADPCM */
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:              /* DMA DAC, 2.6-bit ADPCM Reference */
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:              /* halt DMA operation. 8bit */
537             control (s, 0);
538             break;
539
540         case 0xd1:              /* speaker on */
541             speaker (s, 1);
542             break;
543
544         case 0xd3:              /* speaker off */
545             speaker (s, 0);
546             break;
547
548         case 0xd4:              /* continue DMA operation. 8bit */
549             /* KQ6 (or maybe Sierras audblst.drv in general) resets
550                the frequency between halt/continue */
551             continue_dma8 (s);
552             break;
553
554         case 0xd5:              /* halt DMA operation. 16bit */
555             control (s, 0);
556             break;
557
558         case 0xd6:              /* continue DMA operation. 16bit */
559             control (s, 1);
560             break;
561
562         case 0xd9:              /* exit auto-init DMA after this block. 16bit */
563             s->dma_auto = 0;
564             break;
565
566         case 0xda:              /* exit auto-init DMA after this block. 8bit */
567             s->dma_auto = 0;
568             break;
569
570         case 0xe0:              /* DSP identification */
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:              /* write test reg */
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:              /* read test reg */
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:              /* FIXME */
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
648 static 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
655 static 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
662 static 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              * 0x41 is documented as setting the output sample rate,
748              * and 0x42 the input sample rate, but in fact SB16 hardware
749              * seems to have only a single sample rate under the hood,
750              * and FT2 sets output freq with this (go figure).  Compare:
751              * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
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             /* ADPCM stuff, ignore */
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
844 static 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 = AUD_FMT_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     /* Not sure about that... */
868     /* AUD_set_active_out (s->voice, 1); */
869 }
870
871 static 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
897 static 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:              /* FreeBSD kludge */
917             s->v2x6 = 1;
918             break;
919
920         case 0xc6:
921             s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
922             break;
923
924         case 0xb8:              /* Panic */
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:                  /* write data or command | write status */
941 /*         if (s->highspeed) */
942 /*             break; */
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
975 static 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:                  /* reset */
984         retval = 0xff;
985         break;
986
987     case 0x0a:                  /* read data */
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             /* goto error; */
999         }
1000         break;
1001
1002     case 0x0c:                  /* 0 can write */
1003         retval = s->can_write ? 0 : 0x80;
1004         break;
1005
1006     case 0x0d:                  /* timer interrupt clear */
1007         /* dolog ("timer interrupt clear\n"); */
1008         retval = 0;
1009         break;
1010
1011     case 0x0e:                  /* data available status | irq 8 ack */
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:                  /* irq 16 ack */
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
1044 static 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;    /* master volume 3bits */
1052     s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1053     s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1054     s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1055
1056     /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1057     s->mixer_regs[0x0c] = 0;
1058
1059     /* d5=output filt, d1=stereo switch */
1060     s->mixer_regs[0x0e] = 0;
1061
1062     /* voice volume L d5,d7, R d1,d3 */
1063     s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1064     /* master ... */
1065     s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1066     /* MIDI ... */
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
1074 static 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
1081 static 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
1136 static 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
1153 static 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
1189 static 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
1255 static void SB_audio_callback (void *opaque, int free)
1256 {
1257     SB16State *s = opaque;
1258     s->audio_free = free;
1259 }
1260
1261 static 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
1297 static 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
1355 static 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
1366 static void sb16_initfn (Object *obj)
1367 {
1368     SB16State *s = SB16 (obj);
1369
1370     s->cmd = -1;
1371 }
1372
1373 static 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
1415 static int SB16_init (ISABus *bus)
1416 {
1417     isa_create_simple (bus, TYPE_SB16);
1418     return 0;
1419 }
1420
1421 static Property sb16_properties[] = {
1422     DEFINE_PROP_UINT32 ("version", SB16State, ver,  0x0405), /* 4.5 */
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
1430 static 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
1441 static 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
1449 static 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
1455 type_init (sb16_register_types)
This page took 0.105829 seconds and 4 git commands to generate.