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